17

这个问题有点像结构/设计问题,因为我无法找出执行任务的最佳方式。

在我的 MVC 应用程序中,我使用 DotNetOpenAuth (3.4) 作为我的登录信息提供程序,并且只使用FormsAuthenticationcookie 等标准。

数据库中的当前用户表有:

  • 用户 ID(PK,唯一标识符)
  • OpenId 标识符 (nvarchar(255))
  • OpenIdDisplay (nvarchar(255))
  • 显示名称 (nvarchar(50))
  • 电子邮件 (nvarchar(50))
  • 电话号码 (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");
                }

现在是问题的症结所在:

  1. response.ClaimedIdentifier要针对用户存储的信息是否正确?

  2. FormAuthentication.SetAuthCookie表单身份验证的首选方式吗?或者,还有更好的方法?

  3. 当我调用 SetAuthCookie 时,除了ClaimedIdentifier. 如果我一直提到他们UserId,创建用户是一个更好的主意,然后将其存储UserId在 cookie 中而不是ClaimedIdentifier?

  4. 如果我在多个地方使用该 UserId,我如何从 cookie 中检索它,或者将其存储在其他更合乎逻辑/更有用的地方?

有点啰嗦,但我一直在尝试找出最好的方法来做到这一点/

4

1 回答 1

26

1.response.ClaimedIdentifier 是针对用户存储的正确信息吗?

的。并确保您将其存储在数据库中的列区分大小写。这是一个表模式,演示了如何确保它区分大小写。这来自 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.FormAuthentication.SetAuthCookie 是表单认证的首选方式吗?或者,还有更好的方法?

对于 MVC 应用程序,它肯定是,因为您仍然可以ActionResult从该方法返回您的首选。

3.当我调用 SetAuthCookie 时,除了 ClaimedIdentifier 之外,没有与用户相关的数据。如果我一直在引用他们的 UserId,创建用户是一个更好的主意,然后将该 UserId 存储在 cookie 中而不是 ClaimedIdentifier 中?

这听起来像个人喜好。但我通常会使用 user_id,因为每次 HTTP 请求进入时,它可能会导致更快的数据库查找,这需要您查找任何用户信息。

4.如果我在多个地方使用该 UserId,我如何从 cookie 中检索它,或者将其存储在其他更合乎逻辑/更有用的地方?

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
    }
}
于 2010-02-04T06:35:30.570 回答