MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

ASP.NET MVC 4 使用 OAuth

这个教程向你展示了如何创建一个ASP.NET MVC 4的web应用,能让用户用外部提供方的证书(比如Facebook, Twitter, Microsoft,或Google)登陆,然后将源自那些提供方的一些功能集成进你的web应用。为简单起见,本教程主要讲述与Facebook的证书一起工作。

在你的web应用中启用这些证书提供了一个重要的优势,因为数百万用户已经有这些外部提供方的帐号。如果不是必须创建并且记住一组新的证书,这些用户可能更倾向于注册你的网站。而且当一个用户通过某一个提供方登陆以后,你可以引入提供方的社会化动作。

你将需要构建的

本指南主要有两个目标:

  1. 使用户可以通过开放授权服务者提供的凭据登录
  2. 从第三方获取账号信息并通过在你的站点上完善账户信息

虽然本文的例子只演示了将facebook作为授权服务提供者,但是你可以修改代码去使用任意一个第三方的服务提供者.那些实现的步骤会合你在本文中看到的非常类似.你只有在直接调用第三方提供的API集合时才会发现一些显著的差异.

先决条件

而且,本文假设你具有ASP.NET MVC与Visual Studio的基础知识。如果你需要一个ASP.NET MVC 4的介绍, 请看 ASP.NET MVC 4介绍.

创建工程

在Visual Studio里创建一个新的 ASP.NET MVC 4 Web Application,命名它为 "OAuthMVC"。你可以选择目标为.NET Framework 4.5 或 4中任意一个。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

在 New ASP.NET MVC 4 Project 窗口, 选择 Internet Application 并保留 Razor 作为视图引擎。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

启用一个提供者

当你用Internet Application模板创建出一个MVC 4 web application时,这个工程在App_Start目录创建了一个名为AuthConfig.cs的文件。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

AuthConfig文件包含了针对外部证书提供方的客户注册代码。默认情况下,这些代码被注释掉了,所以没有外部提供者被启用。

01 public static class AuthConfig
02 {
03     public static void RegisterAuth()
04     {
05         // To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter,
06         // you must update this site. For more information visit http://go.microsoft.com/fwlink/?LinkID=252166
07  
08         //OAuthWebSecurity.RegisterMicrosoftClient(
09         //    clientId: "",
10         //    clientSecret: "");
11  
12         //OAuthWebSecurity.RegisterTwitterClient(
13         //    consumerKey: "",
14         //    consumerSecret: "");
15  
16         //OAuthWebSecurity.RegisterFacebookClient(
17         //    appId: "",
18         //    appSecret: "");
19  
20         //OAuthWebSecurity.RegisterGoogleClient();
21     }
22 }

你必须反注册这些代码,以便使用外部的客户证书。你只需反注册你想纳入你的网站的提供方。对本教程,你只要启用Facebook证书。

01 public static class AuthConfig
02 {
03     public static void RegisterAuth()
04     {
05         //OAuthWebSecurity.RegisterMicrosoftClient(
06         //    clientId: "",
07         //    clientSecret: "");
08  
09         //OAuthWebSecurity.RegisterTwitterClient(
10         //    consumerKey: "",
11         //    consumerSecret: "");
12  
13         OAuthWebSecurity.RegisterFacebookClient(
14             appId: "",
15             appSecret: "");
16  
17         //OAuthWebSecurity.RegisterGoogleClient();       
18     }
19 }

注意上面的例子,方法包含了注册参数的空字符串。如果你想现在运行这个应用,应用会抛出一个参数异常,因为这个参数不允许空字符串。为了给出合法的值,你必须像下一节显示的那样,在外部提供方注册你的网站。

在外部提供方注册

要通过来自外部提供方的证书鉴定用户,你必须在提供方注册你的网站。当你注册你的网站时,你将会收到一些参数(比如key或id,以及密码),以便注册客户时包含进去。你必须在你想使用的提供方有一个帐号。

本教程没有呈现出在这些提供方进行注册的所有必须的操作步骤。这些步骤通常是不难的。为了成功的注册你的网站,按照那些网站提供的指示去做。要开始注册你的网站,看看这些开发者网站:

在Facebook注册你的网站时,你可以规定"localhost"为网站域名,"http://localhost/"为网址,像下面图片显示的那样。使用localhost对大多数提供方有效,但目前对Microsoft提供方无效。对Microsoft提供方,你必须包含一个合法的web网站地址。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

在前面的图片中,app id,app secret 和contact email的值被剔除了。当你真正注册你的网站时,那些值将会显现。你要注意app id 和app secret的值,因为你将会把它们加到你的应用,

创建测试用户

如果你不介意使用一个已存在的Facebook帐号来测试你的网站,你可以跳过本节。

你能很容易的在Facebook app管理页面中,为你的应用创建测试用户。你能用这些测试帐号登录你的网站。创建测试用户要点击左边导航格子的Roles链接,并点击Create链接。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

Facebook网站自动创建你申请的数目的测试帐号。

给应用添加来自提供方的id与secret

现在你收到了来自Facebook的id和secret,回到AuthConfig文件把它们作为参数值增加进去。下面显示的数值不是真实的数值。

01 public static class AuthConfig
02 {
03     public static void RegisterAuth()
04     {
05         //OAuthWebSecurity.RegisterMicrosoftClient(
06         //    clientId: "",
07         //    clientSecret: "");
08  
09         //OAuthWebSecurity.RegisterTwitterClient(
10         //    consumerKey: "",
11         //    consumerSecret: "");
12  
13         OAuthWebSecurity.RegisterFacebookClient(
14             appId: "111111111111111",
15             appSecret: "a1a1aa111111111a111a111aaa111111");
16  
17         //OAuthWebSecurity.RegisterGoogleClient();
18     }
19 }

用外部证书登录

那就是在你的网站启用外部证书全部要做的。运行你的应用点击右上角的login链接。模版自动识别出你注册了Facebook作为提供方,并为这个提供方包含了一个按钮。如果你注册了多个提供方,一个按钮对应一个会自动包括进来。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

本教程没有覆盖怎样为外部提供方客制化登录按钮。需要那些信息,可以看使用OAuth/OpenID时客制化登录界面。

点击Facebook按钮以Facebook证书登录。当你选择了外部提供方的一个,你将被重定向到那个网站,并在其服务提示下登录。

下图显示了Facebook的登录界面。它标明你在用名为oauthmvcexample的Facebook帐号登录一个网站。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

用Facebook证书登录以后,一个页面告诉用户这个网站将访问其基本的信息。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

选择 Go to App以后, 用户必须在该网站注册。下图显示了一个用户用Facebook证书登录以后的注册页面。用户名被典型的用一个来自提供方的名字预填充。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

点击 Register 完成注册。关闭浏览器。

你可以看到新的帐号已经被加到你的数据库。在Server Explorer里,打开DefaultConnection数据库并打开Tables目录。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

右击 UserProfile 表选择 Show Table Data

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

你将看到你增加的新帐号。看看webpage_OAuthMembership表中的数据。你会看到为你刚增加的帐号,有关外部提供方的的更多数据。

如果你只是想启用外部鉴权,你已经完成了。然而你可以进一步将来自提供方的信息集成进新用户注册过程,就像下面几节显示的那样。

为附加的用户信息创建模型

正如你在前面几节注意到的,你不需要获得任何附加的信息来使内建的注册去工作。但是,大多数提供方返回了关于用户的附加信息。下面几节显示了怎样保留该信息并将它存入数据库。特别的,你将保留这些值,用户的全名,用户个人主页的URI,以及表明Facebook是否验证了该帐号的一个值。

你将使用代码首先迁移来增加一个表,以便存储附加用户信息。你在增加表到已存在的数据库,因此首先你需要创建一个当前数据库的快照。通过创建当前数据库的快照,你可以以后创建一个仅包含新增表的迁移。要创建当前数据库快照:

  1. 打开 Package Manager Console
  2. 运行命令 enable-migrations
  3. 运行命令 add-migration initial –IgnoreChanges
  4. 运行命令 update-database

现在你要增加新的属性。在Models目录,打开AccountModels.cs文件,找到RegisterExternalLoginModel类。RegisterExternalLoginModel类持有由鉴权提供方返回的数值。增加名为FullName 与 Link的属性,像下面突出的那样。

01 public class RegisterExternalLoginModel
02 {
03     [Required]
04     [Display(Name = "User name")]
05     public string UserName { getset; }
06  
07     public string ExternalLoginData { getset; }
08  
09     [Display(Name = "Full name")]
10     public string FullName { getset; }
11  
12     [Display(Name = "Personal page link")]
13     public string Link { getset; }
14 }

同样在AccountModels.cs, 增加一个名为ExtraUserInformation的新类。这个类代表了将在数据库创建的新表。

1 [Table("ExtraUserInformation")]
2 public class ExternalUserInformation
3 {
4     public int Id { getset; }
5     public int UserId { getset; }
6     public string FullName { getset; }
7     public string Link { getset; }
8     public bool? Verified { getset; }
9 }

在UsersContext类里,增加下面突出的代码,为新类创建一个DbSet属性。

01 public class UsersContext : DbContext
02 {
03     public UsersContext()
04         base("DefaultConnection")
05     {
06     }
07  
08     public DbSet<UserProfile> UserProfiles { getset; }
09     public DbSet<ExternalUserInformation> ExternalUsers { getset; }
10 }

现在你准备好创建新表了。再次打开 Package Manager Console,这次:

  1. 运行命令 add-migration AddExtraUserInformation
  2. 运行命令 update-database

新表现在在数据库出现了。

取得附加的数据

有两个方法获得附加的用户数据。第一个是保留返回的用户数据,默认是在鉴权请求的过程中。第二个方法是特定的调用提供方的 API并请求更多的信息。FullName 与 Link的值自动被Facebook返回。Facebook是否已验证帐号的一个表示数值,是通过一次对Facebook API的调用获得的。首先你要为FullName 和 Link填充值,在此之后,你会得到验证的值。

为了获得额外的用户数据, 打开在Controllers 目录的 AccountController.cs 文件。

这个文件包含了登录、注册以及管理帐号的逻辑。特别的,注意名为ExternalLoginCallbackExternalLoginConfirmation的方法。在这些方法内,你为你的应用可增加客制化的外部登录操作代码。ExternalLoginCallback方法第一行包含:

1 AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
2     Url.Action("ExternalLoginCallback"new { ReturnUrl = returnUrl }));

额外的用户数据在AuthenticationResult对象的ExtraData属性中返回,该对象由VerifyAuthentication方法返回。Facebook在ExtraData属性中包含了下面一些值:

  • id
  • name
  • link
  • gender
  • accesstoken

其他提供方在ExtraData属性中有类似但稍许不同的数据。

如果用户是你的网站的新用户,你会获得一些额外的数据并将其传给确认视图。该方法的最后一块代码只在用户是你网站的新用户 时运行。替代下面这行:

1 return View("ExternalLoginConfirmation"newRegisterExternalLoginModel
2 {
3     UserName = result.UserName,
4     ExternalLoginData = loginData
5 });

替换为这行:

1 return View("ExternalLoginConfirmation"new RegisterExternalLoginModel
2 {
3     UserName = result.UserName,
4     ExternalLoginData = loginData,
5     FullName = result.ExtraData["name"],
6     Link = result.ExtraData["link"]
7 });

这个修改只是包括了FullName 与 Link属性的值。

ExternalLoginConfirmation 方法里,像下面突出显示的那样修改代码,以便保存附加的用户信息。

01 if (user == null)
02 {
03     // Insert name into the profile table
04     UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
05     db.SaveChanges();
06  
07     db.ExternalUsers.Add(newExternalUserInformation
08     {
09         UserId = newUser.UserId,
10         FullName = model.FullName,
11         Link = model.Link
12     });
13     db.SaveChanges();
14  
15     OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
16     OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
17  
18     return RedirectToLocal(returnUrl);
19 }
20 else
21 {
22     ModelState.AddModelError("UserName""User name already exists. Please enter a different user name.");
23 }

调整视图

你从提供方获得的附加的用户数据将被显示于注册页面。

在 ViewsAccount 目录,打开 ExternalLoginConfirmation.cshtml。在已存在的user name字段下面,增加FullName, Link, 和 PictureLink字段。

1 <li>
2     @Html.LabelFor(m => m.FullName)
3     @Html.TextBoxFor(m => m.FullName)
4 </li>
5 <li>
6     @Html.LabelFor(m => m.Link)
7     @Html.TextBoxFor(m => m.Link)
8 </li>

现在你几乎已经准备好运行应用,并且用保存的附加信息注册一个新用户。你必须有一个尚未在该网站注册的帐号。你可以使用一个不同的测试帐号,也可以删除UserProfilewebpages_OAuthMembership 表中的你想重新使用的帐号对应行。通过删除那些行,你能确保该帐号能再次注册。

运行应用并注册新用户。注意这次确认页面包含了更多的数值。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

完成注册以后,关闭浏览器。看看数据库,留心ExtraUserInformation表中的新的值。

为Facebook API安装NuGet包

Facebook 提供了一个 API 给你调用来执行操作。你可以或者通过直接发送HTTP请求,或者通过安装一个帮助发送那些请求的NuGet包,来调用Facebook API。使用一个NuGet包已被本教程显示,但安装NuGet包不是基本的。这个教程显示了如何使用Facebook C# SDK包。还有其他的辅助Facebook API调用的NuGet包。

从 Manage NuGet Packages 窗口,选择 Facebook C# SDK package。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

你将使用 Facebook C# SDK 来调用一个操作,该操作请求用户的 access token (访问令牌)。下一节显示了如何得到access token。

取得 access token

大多数外部的提供方在用户鉴权被验证以后返回一个access token。这个access token非常重要,因为它使你可以调用只能被鉴权用户使用的操作。因此,当你想提供更多功能性时,获得并保存access token是基本的。

取决于外部的提供方,access token可能只在一个有限数值的时间内有效。为了确保你具有一个有效的access token,你要在每次用户登录的时候获得它,并将它保存为session值而不是保存进数据库。

在 ExternalLoginCallback 方法里,access token也被送回到AuthenticationResult对象的ExtraData属性。添加如下突出的代码到 ExternalLoginCallback 以便将 access token 保存进 Session 对象。这些代码在每次用户用Facebook帐号登录时会运行。

01 [AllowAnonymous]
02 public ActionResult ExternalLoginCallback(string returnUrl)
03 {
04     AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
05         Url.Action("ExternalLoginCallback"new { ReturnUrl = returnUrl }));
06     if (!result.IsSuccessful)
07     {
08         return RedirectToAction("ExternalLoginFailure");
09     }
10  
11     if (result.ExtraData.Keys.Contains("accesstoken"))
12     {
13         Session["facebooktoken"] = result.ExtraData["accesstoken"];
14     }
15  
16     if (OAuthWebSecurity.Login(
17         result.Provider,
18         result.ProviderUserId,
19         createPersistentCookie: false))
20     {
21         return RedirectToLocal(returnUrl);
22     }
23  
24     if (User.Identity.IsAuthenticated)
25     {
26         // If the current user is logged in add the new account
27         OAuthWebSecurity.CreateOrUpdateAccount(
28             result.Provider,
29             result.ProviderUserId,
30             User.Identity.Name);
31         return RedirectToLocal(returnUrl);
32     }
33     else
34     {
35         // User is new, ask for their desired membership name
36         string loginData = OAuthWebSecurity.SerializeProviderUserId(
37             result.Provider,
38             result.ProviderUserId);
39         ViewBag.ProviderDisplayName =
40             OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
41         ViewBag.ReturnUrl = returnUrl;
42         return View("ExternalLoginConfirmation"new RegisterExternalLoginModel
43         {
44             UserName = result.UserName,
45             ExternalLoginData = loginData,
46             FullName = result.ExtraData["name"],
47             Link = result.ExtraData["link"]
48         });   
49     }
50 }

尽管这个例子从Facebook获得了一个access token,你可以通过同样的名为“accesstoken”的关键字从任何外部提供方获得access token。

为了防止令牌在用户已退出登录以后仍然保持,你可以添加如下突出的代码到AccountController中的 LogOff方法。

1 [HttpPost]
2 [ValidateAntiForgeryToken]
3 public ActionResult LogOff()
4 {
5     WebSecurity.Logout();
6     Session.Remove("facebooktoken");
7  
8     return RedirectToAction("Index""Home");
9 }

获得需要访问令牌的用户信息

现在你已经保存了access token并且安装了Facebook C# SDK包,你可以一起使用它们去从Facebook请求附加的用户信息。在ExternalLoginConfirmation方法中,通过传递access token的值创建了一个FacebookClient类的实例。请求当前鉴权用户的verified属性值。verified属性表明了Facebook是否已经通过一些其他的方法,比如给蜂窝电话发送一个信息,验证了该帐号。将这个数值保存进数据库。

01 if (user == null)
02 {
03     // Insert name into the profile table
04     UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
05     db.SaveChanges();
06  
07     bool facebookVerified;
08  
09     var client = new Facebook.FacebookClient(Session["facebooktoken"].ToString());
10     dynamic response = client.Get("me"new { fields = "verified" });
11     if (response.ContainsKey("verified"))
12     {
13         facebookVerified = response["verified"];
14     }
15     else
16     {
17         facebookVerified = false;
18     }
19  
20     db.ExternalUsers.Add(newExternalUserInformation
21     {
22         UserId = newUser.UserId,
23         FullName = model.FullName,
24         Link = model.Link,
25         Verified = facebookVerified
26     });
27     db.SaveChanges();
28  
29     OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
30     OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
31  
32     return RedirectToLocal(returnUrl);
33 }

你将需要再一次或者删除数据库中用户的记录,或者使用一个不同的Facebook帐号。

运行应用,并且注册新用户。看看ExtraUserInformation表 Verified属性的值。

总结

本教程中,你创建了集成Facebook来进行用户鉴权并注册数据的网站。你学习了MVC4 web应用创立的默认的行为,以及如何客制化那个默认的行为。

ASP.NET MVC 4 使用 OAuth

这个教程向你展示了如何创建一个ASP.NET MVC 4的web应用,能让用户用外部提供方的证书(比如Facebook, Twitter, Microsoft,或Google)登陆,然后将源自那些提供方的一些功能集成进你的web应用。为简单起见,本教程主要讲述与Facebook的证书一起工作。

在你的web应用中启用这些证书提供了一个重要的优势,因为数百万用户已经有这些外部提供方的帐号。如果不是必须创建并且记住一组新的证书,这些用户可能更倾向于注册你的网站。而且当一个用户通过某一个提供方登陆以后,你可以引入提供方的社会化动作。

你将需要构建的

本指南主要有两个目标:

  1. 使用户可以通过开放授权服务者提供的凭据登录
  2. 从第三方获取账号信息并通过在你的站点上完善账户信息

虽然本文的例子只演示了将facebook作为授权服务提供者,但是你可以修改代码去使用任意一个第三方的服务提供者.那些实现的步骤会合你在本文中看到的非常类似.你只有在直接调用第三方提供的API集合时才会发现一些显著的差异.

先决条件

而且,本文假设你具有ASP.NET MVC与Visual Studio的基础知识。如果你需要一个ASP.NET MVC 4的介绍, 请看 ASP.NET MVC 4介绍.

创建工程

在Visual Studio里创建一个新的 ASP.NET MVC 4 Web Application,命名它为 "OAuthMVC"。你可以选择目标为.NET Framework 4.5 或 4中任意一个。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

在 New ASP.NET MVC 4 Project 窗口, 选择 Internet Application 并保留 Razor 作为视图引擎。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

启用一个提供者

当你用Internet Application模板创建出一个MVC 4 web application时,这个工程在App_Start目录创建了一个名为AuthConfig.cs的文件。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

AuthConfig文件包含了针对外部证书提供方的客户注册代码。默认情况下,这些代码被注释掉了,所以没有外部提供者被启用。

01 public static class AuthConfig
02 {
03     public static void RegisterAuth()
04     {
05         // To let users of this site log in using their accounts from other sites such as Microsoft, Facebook, and Twitter,
06         // you must update this site. For more information visit http://go.microsoft.com/fwlink/?LinkID=252166
07  
08         //OAuthWebSecurity.RegisterMicrosoftClient(
09         //    clientId: "",
10         //    clientSecret: "");
11  
12         //OAuthWebSecurity.RegisterTwitterClient(
13         //    consumerKey: "",
14         //    consumerSecret: "");
15  
16         //OAuthWebSecurity.RegisterFacebookClient(
17         //    appId: "",
18         //    appSecret: "");
19  
20         //OAuthWebSecurity.RegisterGoogleClient();
21     }
22 }

你必须反注册这些代码,以便使用外部的客户证书。你只需反注册你想纳入你的网站的提供方。对本教程,你只要启用Facebook证书。

01 public static class AuthConfig
02 {
03     public static void RegisterAuth()
04     {
05         //OAuthWebSecurity.RegisterMicrosoftClient(
06         //    clientId: "",
07         //    clientSecret: "");
08  
09         //OAuthWebSecurity.RegisterTwitterClient(
10         //    consumerKey: "",
11         //    consumerSecret: "");
12  
13         OAuthWebSecurity.RegisterFacebookClient(
14             appId: "",
15             appSecret: "");
16  
17         //OAuthWebSecurity.RegisterGoogleClient();       
18     }
19 }

注意上面的例子,方法包含了注册参数的空字符串。如果你想现在运行这个应用,应用会抛出一个参数异常,因为这个参数不允许空字符串。为了给出合法的值,你必须像下一节显示的那样,在外部提供方注册你的网站。

在外部提供方注册

要通过来自外部提供方的证书鉴定用户,你必须在提供方注册你的网站。当你注册你的网站时,你将会收到一些参数(比如key或id,以及密码),以便注册客户时包含进去。你必须在你想使用的提供方有一个帐号。

本教程没有呈现出在这些提供方进行注册的所有必须的操作步骤。这些步骤通常是不难的。为了成功的注册你的网站,按照那些网站提供的指示去做。要开始注册你的网站,看看这些开发者网站:

在Facebook注册你的网站时,你可以规定"localhost"为网站域名,"http://localhost/"为网址,像下面图片显示的那样。使用localhost对大多数提供方有效,但目前对Microsoft提供方无效。对Microsoft提供方,你必须包含一个合法的web网站地址。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

在前面的图片中,app id,app secret 和contact email的值被剔除了。当你真正注册你的网站时,那些值将会显现。你要注意app id 和app secret的值,因为你将会把它们加到你的应用,

创建测试用户

如果你不介意使用一个已存在的Facebook帐号来测试你的网站,你可以跳过本节。

你能很容易的在Facebook app管理页面中,为你的应用创建测试用户。你能用这些测试帐号登录你的网站。创建测试用户要点击左边导航格子的Roles链接,并点击Create链接。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

Facebook网站自动创建你申请的数目的测试帐号。

给应用添加来自提供方的id与secret

现在你收到了来自Facebook的id和secret,回到AuthConfig文件把它们作为参数值增加进去。下面显示的数值不是真实的数值。

01 public static class AuthConfig
02 {
03     public static void RegisterAuth()
04     {
05         //OAuthWebSecurity.RegisterMicrosoftClient(
06         //    clientId: "",
07         //    clientSecret: "");
08  
09         //OAuthWebSecurity.RegisterTwitterClient(
10         //    consumerKey: "",
11         //    consumerSecret: "");
12  
13         OAuthWebSecurity.RegisterFacebookClient(
14             appId: "111111111111111",
15             appSecret: "a1a1aa111111111a111a111aaa111111");
16  
17         //OAuthWebSecurity.RegisterGoogleClient();
18     }
19 }

用外部证书登录

那就是在你的网站启用外部证书全部要做的。运行你的应用点击右上角的login链接。模版自动识别出你注册了Facebook作为提供方,并为这个提供方包含了一个按钮。如果你注册了多个提供方,一个按钮对应一个会自动包括进来。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

本教程没有覆盖怎样为外部提供方客制化登录按钮。需要那些信息,可以看使用OAuth/OpenID时客制化登录界面。

点击Facebook按钮以Facebook证书登录。当你选择了外部提供方的一个,你将被重定向到那个网站,并在其服务提示下登录。

下图显示了Facebook的登录界面。它标明你在用名为oauthmvcexample的Facebook帐号登录一个网站。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

用Facebook证书登录以后,一个页面告诉用户这个网站将访问其基本的信息。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

选择 Go to App以后, 用户必须在该网站注册。下图显示了一个用户用Facebook证书登录以后的注册页面。用户名被典型的用一个来自提供方的名字预填充。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

点击 Register 完成注册。关闭浏览器。

你可以看到新的帐号已经被加到你的数据库。在Server Explorer里,打开DefaultConnection数据库并打开Tables目录。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

右击 UserProfile 表选择 Show Table Data

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

你将看到你增加的新帐号。看看webpage_OAuthMembership表中的数据。你会看到为你刚增加的帐号,有关外部提供方的的更多数据。

如果你只是想启用外部鉴权,你已经完成了。然而你可以进一步将来自提供方的信息集成进新用户注册过程,就像下面几节显示的那样。

为附加的用户信息创建模型

正如你在前面几节注意到的,你不需要获得任何附加的信息来使内建的注册去工作。但是,大多数提供方返回了关于用户的附加信息。下面几节显示了怎样保留该信息并将它存入数据库。特别的,你将保留这些值,用户的全名,用户个人主页的URI,以及表明Facebook是否验证了该帐号的一个值。

你将使用代码首先迁移来增加一个表,以便存储附加用户信息。你在增加表到已存在的数据库,因此首先你需要创建一个当前数据库的快照。通过创建当前数据库的快照,你可以以后创建一个仅包含新增表的迁移。要创建当前数据库快照:

  1. 打开 Package Manager Console
  2. 运行命令 enable-migrations
  3. 运行命令 add-migration initial –IgnoreChanges
  4. 运行命令 update-database

现在你要增加新的属性。在Models目录,打开AccountModels.cs文件,找到RegisterExternalLoginModel类。RegisterExternalLoginModel类持有由鉴权提供方返回的数值。增加名为FullName 与 Link的属性,像下面突出的那样。

01 public class RegisterExternalLoginModel
02 {
03     [Required]
04     [Display(Name = "User name")]
05     public string UserName { getset; }
06  
07     public string ExternalLoginData { getset; }
08  
09     [Display(Name = "Full name")]
10     public string FullName { getset; }
11  
12     [Display(Name = "Personal page link")]
13     public string Link { getset; }
14 }

同样在AccountModels.cs, 增加一个名为ExtraUserInformation的新类。这个类代表了将在数据库创建的新表。

1 [Table("ExtraUserInformation")]
2 public class ExternalUserInformation
3 {
4     public int Id { getset; }
5     public int UserId { getset; }
6     public string FullName { getset; }
7     public string Link { getset; }
8     public bool? Verified { getset; }
9 }

在UsersContext类里,增加下面突出的代码,为新类创建一个DbSet属性。

01 public class UsersContext : DbContext
02 {
03     public UsersContext()
04         base("DefaultConnection")
05     {
06     }
07  
08     public DbSet<UserProfile> UserProfiles { getset; }
09     public DbSet<ExternalUserInformation> ExternalUsers { getset; }
10 }

现在你准备好创建新表了。再次打开 Package Manager Console,这次:

  1. 运行命令 add-migration AddExtraUserInformation
  2. 运行命令 update-database

新表现在在数据库出现了。

取得附加的数据

有两个方法获得附加的用户数据。第一个是保留返回的用户数据,默认是在鉴权请求的过程中。第二个方法是特定的调用提供方的 API并请求更多的信息。FullName 与 Link的值自动被Facebook返回。Facebook是否已验证帐号的一个表示数值,是通过一次对Facebook API的调用获得的。首先你要为FullName 和 Link填充值,在此之后,你会得到验证的值。

为了获得额外的用户数据, 打开在Controllers 目录的 AccountController.cs 文件。

这个文件包含了登录、注册以及管理帐号的逻辑。特别的,注意名为ExternalLoginCallbackExternalLoginConfirmation的方法。在这些方法内,你为你的应用可增加客制化的外部登录操作代码。ExternalLoginCallback方法第一行包含:

1 AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
2     Url.Action("ExternalLoginCallback"new { ReturnUrl = returnUrl }));

额外的用户数据在AuthenticationResult对象的ExtraData属性中返回,该对象由VerifyAuthentication方法返回。Facebook在ExtraData属性中包含了下面一些值:

  • id
  • name
  • link
  • gender
  • accesstoken

其他提供方在ExtraData属性中有类似但稍许不同的数据。

如果用户是你的网站的新用户,你会获得一些额外的数据并将其传给确认视图。该方法的最后一块代码只在用户是你网站的新用户 时运行。替代下面这行:

1 return View("ExternalLoginConfirmation"newRegisterExternalLoginModel
2 {
3     UserName = result.UserName,
4     ExternalLoginData = loginData
5 });

替换为这行:

1 return View("ExternalLoginConfirmation"new RegisterExternalLoginModel
2 {
3     UserName = result.UserName,
4     ExternalLoginData = loginData,
5     FullName = result.ExtraData["name"],
6     Link = result.ExtraData["link"]
7 });

这个修改只是包括了FullName 与 Link属性的值。

ExternalLoginConfirmation 方法里,像下面突出显示的那样修改代码,以便保存附加的用户信息。

01 if (user == null)
02 {
03     // Insert name into the profile table
04     UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
05     db.SaveChanges();
06  
07     db.ExternalUsers.Add(newExternalUserInformation
08     {
09         UserId = newUser.UserId,
10         FullName = model.FullName,
11         Link = model.Link
12     });
13     db.SaveChanges();
14  
15     OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
16     OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
17  
18     return RedirectToLocal(returnUrl);
19 }
20 else
21 {
22     ModelState.AddModelError("UserName""User name already exists. Please enter a different user name.");
23 }

调整视图

你从提供方获得的附加的用户数据将被显示于注册页面。

在 ViewsAccount 目录,打开 ExternalLoginConfirmation.cshtml。在已存在的user name字段下面,增加FullName, Link, 和 PictureLink字段。

1 <li>
2     @Html.LabelFor(m => m.FullName)
3     @Html.TextBoxFor(m => m.FullName)
4 </li>
5 <li>
6     @Html.LabelFor(m => m.Link)
7     @Html.TextBoxFor(m => m.Link)
8 </li>

现在你几乎已经准备好运行应用,并且用保存的附加信息注册一个新用户。你必须有一个尚未在该网站注册的帐号。你可以使用一个不同的测试帐号,也可以删除UserProfilewebpages_OAuthMembership 表中的你想重新使用的帐号对应行。通过删除那些行,你能确保该帐号能再次注册。

运行应用并注册新用户。注意这次确认页面包含了更多的数值。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

完成注册以后,关闭浏览器。看看数据库,留心ExtraUserInformation表中的新的值。

为Facebook API安装NuGet包

Facebook 提供了一个 API 给你调用来执行操作。你可以或者通过直接发送HTTP请求,或者通过安装一个帮助发送那些请求的NuGet包,来调用Facebook API。使用一个NuGet包已被本教程显示,但安装NuGet包不是基本的。这个教程显示了如何使用Facebook C# SDK包。还有其他的辅助Facebook API调用的NuGet包。

从 Manage NuGet Packages 窗口,选择 Facebook C# SDK package。

MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth

你将使用 Facebook C# SDK 来调用一个操作,该操作请求用户的 access token (访问令牌)。下一节显示了如何得到access token。

取得 access token

大多数外部的提供方在用户鉴权被验证以后返回一个access token。这个access token非常重要,因为它使你可以调用只能被鉴权用户使用的操作。因此,当你想提供更多功能性时,获得并保存access token是基本的。

取决于外部的提供方,access token可能只在一个有限数值的时间内有效。为了确保你具有一个有效的access token,你要在每次用户登录的时候获得它,并将它保存为session值而不是保存进数据库。

在 ExternalLoginCallback 方法里,access token也被送回到AuthenticationResult对象的ExtraData属性。添加如下突出的代码到 ExternalLoginCallback 以便将 access token 保存进 Session 对象。这些代码在每次用户用Facebook帐号登录时会运行。

01 [AllowAnonymous]
02 public ActionResult ExternalLoginCallback(string returnUrl)
03 {
04     AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
05         Url.Action("ExternalLoginCallback"new { ReturnUrl = returnUrl }));
06     if (!result.IsSuccessful)
07     {
08         return RedirectToAction("ExternalLoginFailure");
09     }
10  
11     if (result.ExtraData.Keys.Contains("accesstoken"))
12     {
13         Session["facebooktoken"] = result.ExtraData["accesstoken"];
14     }
15  
16     if (OAuthWebSecurity.Login(
17         result.Provider,
18         result.ProviderUserId,
19         createPersistentCookie: false))
20     {
21         return RedirectToLocal(returnUrl);
22     }
23  
24     if (User.Identity.IsAuthenticated)
25     {
26         // If the current user is logged in add the new account
27         OAuthWebSecurity.CreateOrUpdateAccount(
28             result.Provider,
29             result.ProviderUserId,
30             User.Identity.Name);
31         return RedirectToLocal(returnUrl);
32     }
33     else
34     {
35         // User is new, ask for their desired membership name
36         string loginData = OAuthWebSecurity.SerializeProviderUserId(
37             result.Provider,
38             result.ProviderUserId);
39         ViewBag.ProviderDisplayName =
40             OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
41         ViewBag.ReturnUrl = returnUrl;
42         return View("ExternalLoginConfirmation"new RegisterExternalLoginModel
43         {
44             UserName = result.UserName,
45             ExternalLoginData = loginData,
46             FullName = result.ExtraData["name"],
47             Link = result.ExtraData["link"]
48         });   
49     }
50 }

尽管这个例子从Facebook获得了一个access token,你可以通过同样的名为“accesstoken”的关键字从任何外部提供方获得access token。

为了防止令牌在用户已退出登录以后仍然保持,你可以添加如下突出的代码到AccountController中的 LogOff方法。

1 [HttpPost]
2 [ValidateAntiForgeryToken]
3 public ActionResult LogOff()
4 {
5     WebSecurity.Logout();
6     Session.Remove("facebooktoken");
7  
8     return RedirectToAction("Index""Home");
9 }

获得需要访问令牌的用户信息

现在你已经保存了access token并且安装了Facebook C# SDK包,你可以一起使用它们去从Facebook请求附加的用户信息。在ExternalLoginConfirmation方法中,通过传递access token的值创建了一个FacebookClient类的实例。请求当前鉴权用户的verified属性值。verified属性表明了Facebook是否已经通过一些其他的方法,比如给蜂窝电话发送一个信息,验证了该帐号。将这个数值保存进数据库。

01 if (user == null)
02 {
03     // Insert name into the profile table
04     UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
05     db.SaveChanges();
06  
07     bool facebookVerified;
08  
09     var client = new Facebook.FacebookClient(Session["facebooktoken"].ToString());
10     dynamic response = client.Get("me"new { fields = "verified" });
11     if (response.ContainsKey("verified"))
12     {
13         facebookVerified = response["verified"];
14     }
15     else
16     {
17         facebookVerified = false;
18     }
19  
20     db.ExternalUsers.Add(newExternalUserInformation
21     {
22         UserId = newUser.UserId,
23         FullName = model.FullName,
24         Link = model.Link,
25         Verified = facebookVerified
26     });
27     db.SaveChanges();
28  
29     OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
30     OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
31  
32     return RedirectToLocal(returnUrl);
33 }

你将需要再一次或者删除数据库中用户的记录,或者使用一个不同的Facebook帐号。

运行应用,并且注册新用户。看看ExtraUserInformation表 Verified属性的值。

总结

本教程中,你创建了集成Facebook来进行用户鉴权并注册数据的网站。你学习了MVC4 web应用创立的默认的行为,以及如何客制化那个默认的行为。

上一篇:IOS笔记 #pragma mark的用法和作用(方便查找和导航代码)


下一篇:命令行下从bak文件恢复sqlserver数据库方法