type Subscription<'T> = 'T -> unit
type Subscribers = ConcurrentBag<Object>
type Subscriptions = ConcurrentDictionary<Type, Subscribers>
type PubSub = Subscriptions * PubSubExceptionHandler
如何在一个地方验证所有控制器的Request.Headers [“Authorization”]?
答案 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]
属性忽略它。