NET问答: 如何集中化统一验证 Authorization
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NET问答: 如何集中化统一验证 Authorization相关的知识,希望对你有一定的参考价值。
咨询区
Felipe Deveza:
我自己实现了一个 basic 验证,现在我的做法是在每一个 Action 中都提取 Request.Headers["Authorization"]
进行权限验证。
[HttpGet]
public IActionResult Get()
{
string token = Request.Headers["Authorization"];
// Validate token.
}
[HttpPost]
public IActionResult Post(int id)
{
string token = Request.Headers["Authorization"];
// Validate token.
}
请问我是否可以在某一个集中地方做 Request.Headers["Authorization"]
的全局验证呢?
回答区
miechooy:
你可以通过自定义中间件的方式对 header
进行统一验证,然后决定是否传给后端的的 Controller。
中间件的逻辑大概如下:
public class YourMidllewareClass
{
public async Task Invoke(HttpContext context)
{
string token = context.Request.Headers["Authorization"];
//do the checking
if (token == null)
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Access denied!");
return;
}
//pass request further if correct
await _next(context);
}
}
有了中间件之后,接下来通过 IApplicationBuilder 将其注入到Http请求管道中,参考如下代码:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConnectionManager conn, ILoggerFactory loggerFactory)
{
app.UseMiddleware<YourMidllewareClass>();
}
Matheus Lacerda:
在 ASP.NET Core 中,你可以使用内置的 AuthenticationHandler 类,详细文档请参考:https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x 。
刚好我的项目中有一个自定义验证
功能。
Startup.ConfigureServices:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Custom Scheme";
options.DefaultChallengeScheme = "Custom Scheme";
}).AddCustomAuth(o => { });
Startup.Configure:
app.UseAuthentication();
finally
internal class CustomAuthenticationHandler :
AuthenticationHandler<CustomAuthenticationOptions>
{
public CustomAuthenticationHandler(IOptionsMonitor<CustomAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) :
base(options, logger, encoder, clock)
{
}
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
try
{
// Your auth code here
// Followed by something like this:
return AuthenticateResult.Success(
new AuthenticationTicket(
new ClaimsPrincipal(
new ClaimsIdentity(
new List<Claim>() { new Claim(ClaimTypes.Sid, Id.ToString()) },
Scheme.Name)),
Scheme.Name));
}
catch
{
return AuthenticateResult.Fail("Error message.");
}
}
}
这样配置之后,所有对Controller的请求都会先经过 authentication ,如果某些 Controller 有特殊需求,可以使用 [AllowAnonymous]
忽略它。
点评区
说实话在.netcore 时代实现这种统一验证的需求不要太简单了,中间件这块也是大家必须理解的基础知识。
以上是关于NET问答: 如何集中化统一验证 Authorization的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 OWIN Jwt Bearer Authentication 记录身份验证结果