在我的MVC应用程序中,我使用的是DotNetOpenAuth(3.4)作为我的登录信息提供者,并且只使用标准的FormsAuthentication for cookies等。
DB中的当前用户表有:
> UserId(PK,uniqueidentifier)
> OpenIdIdentifier(nvarchar(255))
> OpenIdDisplay(nvarchar(255))
>显示名称(nvarchar(50))
>电子邮件(nvarchar(50))
> PhoneNumber(nvarchar(50))
由于UserId是用户的清晰标识符(他们应该能够在以后更改其OpenId提供程序),所以它是其他表链接到(对于用户)的关键。
这是当前的代码,在成功的身份验证中,创建一个临时用户并重定向到Create Action。
switch (response.Status) { case AuthenticationStatus.Authenticated: FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier,false); var users = new UserRepository(); if (!users.IsOpenIdAssociated(response.ClaimedIdentifier)) { var newUser = new DueDate.Models.User(); newUser.OpenIdIdentifer = response.ClaimedIdentifier; newUser.OpenIdDisplay = response.FriendlyIdentifierForDisplay; TempData["newUser"] = newUser; return this.RedirectToAction("Create"); }
现在呢是这个问题的关键:
> response.ClaimedIdentifier是否正确存储对用户的信息?
> FormAuthentication.SetAuthCookie是表单验证的首选方式吗?还是有更好的方法?
>当我打电话给SetAuthCookie时,除了ClaimedIdentifier之外,没有与用户有关的数据。如果我一直引用他们的UserId,创建用户是一个更好的主意,然后将该UserId存储在cookie中而不是ClaimedIdentifier?
>如果我在多个地方使用该UserId,我该如何从cookie中检索它,或将其存储在更多的逻辑/有用的地方?
有点长,但我一直在努力找出最好的方法来做这个/
解决方法
1.Is the response.ClaimedIdentifier the correct piece of information to be storing against a user?
是。并确保将其存储在数据库中的列区分大小写。这是一个表模式,演示如何确保它区分大小写。这来自DotNetOpenAuth项目模板的数据库模式。指定的排序规则的“CS”位代表区分大小写。
CREATE TABLE [dbo].[AuthenticationToken] ( [AuthenticationTokenId] INT IDENTITY (1,1) NOT NULL,[UserId] INT NOT NULL,[OpenIdClaimedIdentifier] NVARCHAR (250) COLLATE sql_Latin1_General_CP1_CS_AS NOT NULL,[OpenIdFriendlyIdentifier] NVARCHAR (250) NULL,[CreatedOn] DATETIME NOT NULL,[LastUsed] DATETIME NOT NULL,[UsageCount] INT NOT NULL );
2.Is FormAuthentication.SetAuthCookie the preferred way to forms authentication? Or is there a better way?
对于MVC应用,它肯定是,因为您仍然可以从该方法返回您首选的ActionResult。
3.When I call SetAuthCookie,there is no data relating to the user except for the ClaimedIdentifier. If I’m consistently referring to their UserId,is a better idea to create the user,then store that UserId in the cookie instead of the ClaimedIdentifier?
这听起来像个人喜好。但是我通常会使用user_id,因为每次HTTP请求都需要您查找任何用户信息,因此可能会导致更快的数据库查找。
4.If I’m using that UserId in a number of places,how do I either retrieve it from the cookie,or store it somewhere else more logical/useful?
FormsAuthentication确实提供了一种在其加密的cookie中存储更多信息而不仅仅是用户名,但是比您期望使用它更难。 DotNetOpenAuth的Web SSO RP示例中提供了这个代码段:
const int TimeoutInMinutes = 100; // TODO: look up the right value from the web.config file var ticket = new FormsAuthenticationTicket( 2,// magic number used by FormsAuth response.ClaimedIdentifier,// username DateTime.Now,DateTime.Now.AddMinutes(TimeoutInMinutes),false,// "remember me" "your extra data goes here"); HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,FormsAuthentication.Encrypt(ticket)); Response.SetCookie(cookie); Response.Redirect(Request.QueryString["ReturnUrl"] ?? FormsAuthentication.DefaultUrl);
然后,您可以在以后的HTTP请求中获取额外的数据:
var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie != null) { var ticket = FormsAuthentication.Decrypt(cookie.Value); if (!string.IsNullOrEmpty(ticket.UserData)) { // do something cool with the extra data here } }