一起使用承载令牌和cookie身份验证


68

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

该站点还具有几个需要保护的常规MVC页面,但使用cookie身份验证

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

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

但是,这似乎有一个副作用,就是每当从SPA发送AJAX请求时,它都会在标头cookie中发送承载令牌。

而我真正想要的行为是将承载令牌用于WebAPI调用,仅将cookie用于MVC调用。

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

是否可以通过某种方法在一个应用程序中进行这种混合模式身份验证?也许通过路径/路由过滤器?

Answers:


50

我想我已经解决了:

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页面一旦登录(使用AuthenticationManager)就使用cookie。


2
史蒂夫,我将做同样的事情。我关心的一个问题是cookie和令牌(即本地存储)不同步。换句话说,cookie和令牌是否需要同时到期,或者当缺少一个或另一个时是否存在一种机制来优雅地处理?
ThisGuy 2014年

4
顺便说一句,CookieAuthenticationOptions中还有一个名为“ CookieHttpOnly”的选项,它将阻止JavaScript将cookie传递给您的API。
ThisGuy 2014年

4
@Steve,只想澄清一件事。您是否在SPA和MVC部件中使用单独的登录页面?或者您可以通过单个登录页面实现此目的?如果是这种情况,您该怎么做?
亚历山大·博伊琴科

3
@ThisGuy这是不正确的。“ CookieHttpOnly”只会阻止在JavaScript中读取cookie的值,而不会阻止在AJAX请求中发送cookie。
丹·特纳

4
对于那些想知道为什么找不到SuppressDefaultHostAuthentication()和HostAuthenticationFilter的人:您需要安装此软件包:通过nuget:Install-Package Microsoft.AspNet.WebApi.Owin
Benjamin Martin

1

您可以在仅HTTP模式下将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.UseAuthentification();
app.UseMvc();

如果此请求带有令牌cookie,则上述代码会将jwt令牌添加到http请求标头中;


3
我认为问题不在于asp.net核心
anatol
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.