我有一个单页应用程序 - 或多或少基于 MVC5 SPA 模板 - 使用不记名令牌进行身份验证。
该站点还有几个需要保护的传统 MVC 页面,但使用 cookie 身份验证。
在 Startup.Auth 我可以启用两种类型的授权:
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOAuthBearerTokens(OAuthOptions);
但是,这似乎有一个副作用,因为每当从 SPA 发送 AJAX 请求时,它都会发送标头中的不记名令牌和 cookie。
而我真正想要的行为是只有承载令牌用于 WebAPI 调用,只有 cookie 用于 MVC 调用。
我还希望 MVC 调用在未授权时重定向到登录页面(设置为 CookieAuthenticationOption),但显然我不希望在进行 API 调用时发生这种情况。
有没有办法在一个应用程序中进行这种类型的混合模式身份验证?也许通过路径/路由过滤器?
我想我解决了这个问题:-
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)。
您可以在 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 请求标头;
Install-Package Microsoft.AspNet.WebApi.Owin