36

我正在尝试了解 MVC 5 中单页应用程序模板中新的 OWIN Bearer Token 身份验证过程。如果我错了,请纠正我,对于 OAuth 密码客户端身份验证流程,Bearer Token 身份验证通过检查 http 授权请求标头来工作对于承载访问令牌代码来查看请求是否经过身份验证,它不依赖 cookie 来检查特定请求是否经过身份验证。

根据这篇文章:

使用 Web API 示例进行 OWIN 不记名令牌身份验证

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    using (IdentityManager identityManager = _identityManagerFactory.CreateStoreManager())
    {
        if (!await identityManager.Passwords.CheckPasswordAsync(context.UserName, context.Password))
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }

        string userId = await identityManager.Logins.GetUserIdForLocalLoginAsync(context.UserName);
        IEnumerable<Claim> claims = await GetClaimsAsync(identityManager, userId);
        ClaimsIdentity oAuthIdentity = CreateIdentity(identityManager, claims,
            context.Options.AuthenticationType);
        ClaimsIdentity cookiesIdentity = CreateIdentity(identityManager, claims,
            _cookieOptions.AuthenticationType);
        AuthenticationProperties properties = await CreatePropertiesAsync(identityManager, userId);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }
}

GrantReourceOwnerCredentials 函数不仅使用以下行组成票证: context.Validated(ticket); 但它也组成一个 cookie 身份,并使用以下行将其设置为 cookie: context.Request.Context.Authentication.SignIn(cookiesIdentity);

所以我的问题是,这个函数中 cookie 的确切目的是什么?AuthenticationTicket 不应该足以用于身份验证目的吗?

4

3 回答 3

37

在 SPA 模板中,实际上启用了两种独立的身份验证机制——cookie 身份验证和令牌身份验证。这启用了 MVC 和 Web API 控制器操作的身份验证,但需要一些额外的设置。

如果您查看 WebApiConfig.Register 方法,您将看到这行代码:

    config.SuppressDefaultHostAuthentication();

这告诉 Web API 忽略 cookie 身份验证,从而避免了许多问题,这些问题在您在问题中发布的链接中进行了解释:

“...SPA 模板也将应用程序 cookie 中间件启用为活动模式,以启用 MVC 身份验证等其他场景。因此,如果请求具有会话 cookie 但没有承载令牌,则 Web API 仍将通过身份验证。这可能不是你的如果你的 API 很容易受到 CSRF 攻击,另一个负面影响是,如果请求未经授权,两个中间件组件都会向它提出挑战。cookie 中间件会将 401 响应更改为 302 以重定向到登录页面。这也不是你想要的 Web API 请求。”

因此,现在config.SuppressDefaultHostAuthentication()调用需要授权的 Web API 调用将忽略随请求一起自动发送的 cookie,并查找以“Bearer”开头的 Authorization 标头。MVC 控制器将继续使用 cookie 身份验证,并且对令牌身份验证机制一无所知,因为它一开始就不太适合网页身份验证。

于 2014-03-18T15:04:44.700 回答
3

cookie 的存在也让我感到困惑,因为它显然在不记名令牌认证场景中是不必要的......在这篇文章中,作者剖析了个人账户模板,并对 cookie 有以下说法:

该方法还设置应用程序 cookie。我看不出有什么好的理由。

我的猜测是,模板的作者想要展示不同类型的身份验证逻辑的示例,在这种特殊情况下,他们想要展示身份验证信息如何存储在不记名令牌身份验证 JSON 有效负载中,以及标准身份验证 cookie。

除了加密票证之外,JSON 身份验证负载还设置为还包括一个额外的(不必要的)未加密属性(用户 ID),这一事实似乎支持了这一理论:

var properties = CreateProperties(user.UserName);
var ticket = new AuthenticationTicket(oAuthIdentity, properties);

模板的作者似乎想提供一些有用的示例,而不是实现不记名令牌认证所需的最低限度。上面的链接帖子中也提到了这一点。

于 2014-02-06T19:29:37.393 回答
-1

cookie 有一个重要用途。它的值包含可以由您页面上的客户端 javascript 提取的不记名令牌。这意味着如果用户点击 F5 或刷新页面,cookie 通常会持续存在。然后,当页面重新加载时,您的客户端 javascript 可以从 cookie 中获取不记名令牌。

于 2015-01-13T23:23:09.620 回答