MVC.Net核心MVC 21中HttpContext的插件授权头
我在.Net Core 2.1应用程序的会话中存储了一个Jwt承载令牌。在我的中间件中,我通过以下方式拦截请求并将令牌附加到头:MVC.Net核心MVC 21中HttpContext的插件授权头,.net,model-view-controller,asp.net-core,.net,Model View Controller,Asp.net Core,我在.Net Core 2.1应用程序的会话中存储了一个Jwt承载令牌。在我的中间件中,我通过以下方式拦截请求并将令牌附加到头: httpContext.Request.Headers.Add("Authorization", $"Bearer {token}"); 这目前不起作用,因为我在受保护的路线上遇到未经授权的攻击。如果我使用邮递员进行相同的呼叫,并在报头中传递授权和承载令牌,那么它可以工作 我需要对http.Request做什么更改才能使其可接受 使用Jwt启动的部分: var si
httpContext.Request.Headers.Add("Authorization", $"Bearer {token}");
这目前不起作用,因为我在受保护的路线上遇到未经授权的攻击。如果我使用邮递员进行相同的呼叫,并在报头中传递授权和承载令牌,那么它可以工作
我需要对http.Request做什么更改才能使其可接受
使用Jwt启动的部分:
var signingKey=密钥
services.AddSingleton<IJwtFactory, JwtFactory>();
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
// Configure JwtIssuerOptions
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = Issuer;
options.Audience = Audience;
options.SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = Issuer,
ValidateAudience = true,
ValidAudience = Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
})
.AddCookie(cfg => cfg.SlidingExpiration = true);
如评论中所述,在调用
UseSiteRouteMiddleware
时,身份验证中间件已经处理完毕
所以现在做任何事情都太晚了。更改中间件的执行顺序。
在useAuthentication()之前,将useSiteRouteMiddlware
放在靠近开头的位置
根据注册顺序确定中间件的执行顺序
在启动中添加中间件组件的顺序。Configure
方法定义在请求时调用中间件组件的顺序以及响应的相反顺序。订单对于安全性、性能和功能至关重要
这就是注册身份验证中间件的原因,该中间件最终将在传入的HTTP请求中查找JWT承载令牌,并使用该令牌基于该值对用户进行身份验证
由于该中间件是您注册的第一个中间件,因此它也将作为第一个中间件运行,然后再运行管道中的任何其他中间件。由于app.UseSiteRouteMiddleware()
调用稍后进行,因此修改传入HTTP请求的自定义中间件也将稍后运行。因此,它将在请求已用于身份验证目的后修改该请求
如果希望在有机会重写HTTP请求后进行身份验证,则必须将app.UseSiteRouteMiddleware()移动到app.UseAuthentication()调用之前
但是请注意,由于自定义中间件使用会话,因此会话中间件也必须在自定义中间件之前运行。毕竟,您的流程应该是这样工作的:
检索会话信息(会话中间件)
调整HTTP请求头(SiteRouteMiddleware)
验证用户(验证中间件)
因此,您必须按此顺序设置这三个中间件:
app.UseSession();
app.UseSiteRouteMiddleware(getRoutes);
app.UseAuthentication();
也就是说,您存储JWT的方法非常不统一。使用承载令牌的身份验证通常被认为是无状态的,因为客户端显式地传递对用户进行身份验证所需的令牌。这与常见的基于cookie的身份验证不同,在这种身份验证中,数据作为请求的一部分隐式地通过cookie传递
具有讽刺意味的是,使用会话中间件存储JWT承载令牌实际上正是这样做的:默认情况下,会话中间件使用会话cookie恢复以前的用户会话。因此,对于您的解决方案,您基本上使用了不同的cookie来启用身份验证
除非您对此设计有很好的理由,否则我强烈建议您切换到标准的cookie身份验证,它只将身份存储在cookie中,而不是存储在JSON Web令牌中。这通常也会降低身份验证设置的复杂性,同时使其得到更好的支持。同时,您还将失去使用额外会话管理的要求,这通常被建议不要使用(除非您有充分的理由)
如果您需要“正常”的JWT承载身份验证,例如,如果您的应用程序也被API客户端访问,那么请注意,在应用程序中同时使用JWT承载身份验证和cookie身份验证并没有什么错。这样,您就可以自由选择最适合每种情况的身份验证样式。显示您的配置代码,否则我们将无法帮助您猜测UseXxx
方法部分仍然缺少配置部分。中间件是按照它们注册到UseXxx
middleware的顺序执行的,因此,如果您在认证中间件之前或之后注册中间件,那么这一部分可能仍然很重要,正如我所想的那样。调用UseSiteRouteMiddle软件时,身份验证中间件已经处理完毕。更改顺序,将您的useSiteRouteMiddle软件
放在靠近开头的位置,然后再将其固定在useAuthentication
之前。谢谢你的帮助。
app.UseAuthentication();
app.UseSession();
app.UseSiteRouteMiddleware(getRoutes);
app.UseAuthentication();