.NET Core 2:强制身份验证处理程序在中间件之前运行?

时间:2018-10-06 16:53:49

标签: asp.net-mvc authentication asp.net-core-2.0

将api端点从.NET Core 1 Web项目中提取到仅.NET Core 2 API的项目中。我对auth(-orization和-entication)的经验充其量很少,这主要是因为我从事的大多数项目已经为auth设置过,并且/或者已经是AD环境。

站点的API部分使用预共享的令牌包含在每个请求的标头中。此令牌是所有身份验证,用户标识,权限等的关键。用户信息(例如,您是谁,您可以做什么)包含在自定义CurrentContext类中。

Core 1项目使用中间件(ContextMiddleware)初始化在DI中注册为CurrentContext的{​​{1}}实例。在调用scoped类时,已经调用了自定义auth处理程序,已经检查了必要的标头令牌,通过了身份验证检查,并创建了主体。因此,严重依赖于现有主体的ContextMiddleware类可以构建ContextMiddleware和大量信息来了解谁在呼叫。

Core 2项目最终在身份验证处理程序之前运行CurrentContext,我不知道如何强制这两个命令互换。

相关代码段:

ContextMiddleware

如果需要更多代码段以获取更多信息,请告诉我。如何强制我的身份验证处理程序的HandleAuthenticateAsync()在调用 public class Startup { public void ConfigureServices(IServiceCollection services) { // ... // https://geeklearning.io/how-to-migrate-your-authentication-middleware-to-asp-net-core-2-0/ services.AddAuthentication( options => { options.DefaultScheme = UserTokenAuthenticationDefaults.AuthenticationScheme; } ).AddUserTokenAuthentication(UserTokenAuthenticationDefaults.AuthenticationScheme, UserTokenAuthenticationDefaults.AuthenticationScheme, o => { } ); // ... } public void Configure(IApplicationBuilder app /*...*/) { if (env.IsDevelopment()){ app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/error/500"); } app.UseStaticFiles(); app.UseAuthentication(); app.UseMiddleware<ContextMiddleware>(); app.UseMvc(); } } 之前运行?

1 个答案:

答案 0 :(得分:1)

我也在处理这个问题,我们发现最好支持我们制定的“动态”身份验证方案,然后允许调用选择器来做出身份验证类型决定。

根据ASP.NET Core标准在代码库中的某个位置添加一个DynamicAuthenticationDefaults.AuthenticationScheme = "Dynamic";常量,然后在启动类的ConfigureServices中添加动态方案:

.AddAuthentication( options =>
{
    options.DefaultScheme = DynamicAuthenticationDefaults.AuthenticationScheme;
    options.DefaultAuthenticateScheme = DynamicAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = DynamicAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = DynamicAuthenticationDefaults.AuthenticationScheme;
    options.DefaultSignOutScheme = DynamicAuthenticationDefaults.AuthenticationScheme;
} )
.AddYourCustomAuthentication( YourCustomAuthenticationDefaults.AuthenticationScheme, YourCustomAuthenticationDefaults.AuthenticationScheme, options => { } )
.AddPolicyScheme( DynamicAuthenticationDefaults.AuthenticationScheme, DynamicAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.ForwardDefaultSelector = DynamicAuthenticationSchemaSelector.Evaluate;
} );

然后在自定义DynamicAuthenticationSchemaSelector类中实现该评估方法:

public static class DynamicAuthenticationSchemaSelector
{
    public static string Evaluate( HttpContext context )
    {
        string result;

        var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();

        if( !string.IsNullOrEmpty( authHeader ) && authHeader.StartsWith( YourCustomAuthenticationDefaults.AuthenticationScheme ) )
        {
            result = YourCustomAuthenticationDefaults.AuthenticationScheme;
        }
        else
        {
            result = IdentityConstants.ApplicationScheme;
        }

        return result;
    }
}

您将获得正确的身份验证中间件处理。

您也不需要将其称为“动态”,它仅用于遵循最佳实践/模式-任何字符串都足够。