【问题标题】:Using bearer tokens and cookie authentication together一起使用不记名令牌和 cookie 身份验证
【发布时间】:2014-01-24 01:54:32
【问题描述】:

我有一个单页应用程序 - 或多或少基于 MVC5 SPA 模板 - 使用 承载令牌 进行身份验证。

该网站还有几个需要保护的传统 MVC 页面,但使用 cookie 身份验证

在 Startup.Auth 中,我可以启用两种类型的授权:

app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOAuthBearerTokens(OAuthOptions);

但是,这似乎有一个副作用,即每当从 SPA 发送 AJAX 请求时,它都会发送标头中的不记名令牌 cookie。

而我真正想要的行为是不记名令牌用于 WebAPI 调用,而仅 cookie 用于 MVC 调用。

我还希望 MVC 调用在未授权时重定向到登录页面(设置为 CookieAuthenticationOption),但显然我不希望在进行 API 调用时发生这种情况。

有没有办法在一个应用程序中进行这种类型的混合模式身份验证?也许通过路径/路由过滤器?

【问题讨论】:

    标签: asp.net-mvc asp.net-web-api oauth-2.0 owin


    【解决方案1】:

    你可以在http-only模式下将jwt令牌添加到cookie(这里我的jwt令牌cookie名称是“access_token”),并制作这样的中间件

    public class JwtCookieMiddleware
    {
        private readonly RequestDelegate _next;
    
        public JwtCookieMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        public Task Invoke(HttpContext ctx)
        {
            if (ctx.Request.Cookies.TryGetValue("access_token", out var accessToken))
            {
                if (!string.IsNullOrEmpty(accessToken))
                {
                    string bearerToken = String.Format("Bearer {0}", accessToken);
                    ctx.Request.Headers.Add("Authorization",bearerToken);
                }
            }
            return this._next(ctx);
        }
    }
    public static class JwtCookieMiddlewareExtensions
    {
        public static IApplicationBuilder UseJwtCookie(this IApplicationBuilder build)
        {
            return build.UseMiddleware<JwtCookieMiddleware>();
        }
    }
    

    你需要像这样在启动时使用中间件:

    app.UseJwtCookie();
    app.UseAuthentication();
    app.UseMvc();
    

    如果这个请求带有令牌cookie,上面的代码会将jwt令牌添加到http请求头中;

    【讨论】:

    • 我相信问题不在于 asp.net core
    【解决方案2】:

    我想我解决了这个问题:-

    Startup.Auth 正在连接 OWIN 管道,因此在其中包含 Cookie 和令牌是正确的。但是对 cookie 选项的一项更改指定了它应该应用于的身份验证类型:

    CookieOptions = new CookieAuthenticationOptions
    {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie   
    };
    

    然后我需要将 WebAPI 配置为仅使用令牌:

    public static void Configure(HttpConfiguration config)
    {
       // Configure Web API to use only bearer token authentication.
       config.SuppressDefaultHostAuthentication();
       config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
    }
    

    这似乎达到了我想要的。 WebAPI 只使用不记名令牌而不使用 cookie,一些传统的 MVC 页面在登录后使用 cookie(使用 AuthenticationManager)。

    【讨论】:

    • 史蒂夫,我也要做同样的事情。我担心的一个问题是 cookie 和令牌(即本地存储)不同步。换句话说,cookie 和 token 是否需要同时过期,或者是否有一种机制可以在其中一个丢失时优雅地处理?
    • 顺便说一句,CookieAuthenticationOptions 中还有一个名为“CookieHttpOnly”的选项,它将阻止 JavaScript 将 cookie 传递给您的 API。
    • @Steve,只想澄清一件事。您是否在 SPA 和 MVC 部分中使用单独的登录页面?或者您可以通过单一登录页面实现这一目标?如果是case你怎么做?
    • @ThisGuy 这是不正确的。 “CookieHttpOnly”只会阻止 cookie 的值在 JavaScript 中被读取,它不会阻止 cookie 在 AJAX 请求中发送。
    • 对于那些想知道为什么找不到 SuppressDefaultHostAuthentication() 和 HostAuthenticationFilter 的人:您需要安装此软件包:通过 nuget:Install-Package Microsoft.AspNet.WebApi.Owin
    猜你喜欢
    • 2023-04-02
    • 2018-04-22
    • 1970-01-01
    • 2014-10-13
    • 2017-08-16
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多