如何在一个地方验证所有控制器的Request.Headers [“Authorization”]?

时间:2017-08-03 21:40:19

标签: c# asp.net-core .net-core

type Subscription<'T> = 'T -> unit
type Subscribers = ConcurrentBag<Object>
type Subscriptions = ConcurrentDictionary<Type, Subscribers>
type PubSub = Subscriptions * PubSubExceptionHandler

如何在一个地方验证所有控制器的Request.Headers [“Authorization”]?

2 个答案:

答案 0 :(得分:6)

您可以创建和使用自定义中间件,您可以在其中检查标头并验证是否应将其传递给控制器​​。

创建中间件类并在Startup.cs中对其进行重新同步,如下所示:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConnectionManager conn, ILoggerFactory loggerFactory)
 {
            app.UseMiddleware<YourMidllewareClass>();
 }

在中间件类中创建Invoke方法。在每个请求跳转到任何控制器之前,将调用此方法。

 public async Task Invoke(HttpContext context)
        {
            string token = Request.Headers["Authorization"];
            //do the checking

            //pass request further if correct
            await _next(context);
        }

就我而言,你必须在UseMvc()方法之前重新启动你的中间件,以确保在Mvc管道之前调用你的Invoke()。

答案 1 :(得分:1)

对于ASP.NET Core 2.0,有些东西已经改变,你也可以使用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();

最后:

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.");
        }
    }
}

这样,对控制器的所有调用都将通过身份验证中间件,如有必要,您可以使用控制器上的[AllowAnonymous]属性忽略它。