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 。

刚好我的项目中有一个自定义验证功能。

  1. Startup.ConfigureServices:


    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "Custom Scheme";
        options.DefaultChallengeScheme = "Custom Scheme";
    }).AddCustomAuth(o => { });

  1. Startup.Configure:


 app.UseAuthentication();

  1. 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的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC过滤器

使用一个文件集中管理你的 Nuget 依赖版本号

如何使用 OWIN Jwt Bearer Authentication 记录身份验证结果

MySQL如何配置读写分离?

NET问答: 如何从 event 中移除所有的 handler ?

争议 | 分布式存储 vs 集中统一存储,保险行业核心数据库存储如何选?