简体   繁体   English

如何在ASP.NET核心中间件中强制执行实际的身份验证工作流

[英]How to force actual authentication workflow in ASP.NET core middle ware

I want to inject some application context that is based on authenticated user into the execution context so that business/service layers can use it transparently. 我想将一些基于身份验证的用户的应用程序上下文注入执行上下文中,以便业务/服务层可以透明地使用它。 I am planning to use middleware for setting up the same. 我打算使用中间件进行设置。 Sample code in startup is 启动示例代码为

app.UseAuthentication();

// my custom middleware
app.Use(async (context, next) =>
{
    // use context.User to build the application context 
    // ...

    // inject into execution context
    // ...
}

app.UseMvc(..)

Unfortunately, HttpContext.User.Identity.IsAuthenticated remains false in my custom middleware. 不幸的是,在我的自定义中间件中,HttpContext.User.Identity.IsAuthenticated仍然为false。 Actual authentication based on JWT Tokens gets triggered when MVC Authorization filters are hit. 命中MVC授权过滤器时,将触发基于JWT令牌的实际身份验证。 So how can I overcome this issue? 那么我该如何克服这个问题呢? Is there a way to know when actual authentication stage is finished (similar to global.asax in classic ASP.NET pipeline) or how can I enforce authentication handlers in my middleware. 有没有办法知道实际的身份验证阶段何时完成(类似于经典ASP.NET管道中的global.asax),或者如何在中间件中强制实施身份验证处理程序。 I tried playing with extension methods context.AuthenticateAsync to force the construction of actual user principal but in vain. 我尝试使用扩展方法context.AuthenticateAsync强制构建实际的用户主体,但徒劳无功。

Another issue that I hit is carrier for my application context. 我遇到的另一个问题是应用程序上下文的载体。 I earlier chose AsycLocal<T> but found out that what I set in my middleware is not available at downstream code. 我之前选择了AsycLocal<T>但是发现我在中间件中设置的内容在下游代码中不可用。 So currently, I am using HttpContext.Items to carry my application context which will work but I am curious to know why AsycLocal<T> failed. 因此,当前,我正在使用HttpContext.Items承载可以正常运行的应用程序上下文,但我AsycLocal<T>知道为什么AsycLocal<T>失败。 Is it not guaranteed to be carried over execution context in ASP.NET pipeline? 是否不保证可以在ASP.NET管道的执行上下文中携带?

As requested, ConfigureServices part 根据要求,ConfigureServices部分

    // Add Azure AD JWT Bearer Token support for API authentication
    services.AddAuthentication(AzureADDefaults.JwtBearerAuthenticationScheme)
                       .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
    ...
    // Add Azure AD OpenID authentication support for interactive UI
    services.AddAzureAdV2Authentication(Configuration);

Also found need for adding schemes in policy for multiple schemes to work 还发现需要在策略中添加方案以使多个方案起作用

        // Add MVC with authentication/authorization
        services.AddMvc(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes(AzureADDefaults.OpenIdScheme,
                    AzureADDefaults.JwtBearerAuthenticationScheme)
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })

Finally, in my middleware, I was trying to enforce authentication using snippet such as 最后,在我的中间件中,我尝试使用如下代码段强制执行身份验证:

     if (!context.User.Identity.IsAuthenticated)
     {
          if(context.Request.Headers.ContainsKey(HeaderNames.Authorization))
          {
               await context.AuthenticateAsync(
                   AzureADDefaults.JwtBearerAuthenticationScheme);
          }
          else
          {
              // issue OpenID challange
              ...
          }
       }

      // here, I still found context.User.Identity.IsAuthenticated false

app.UseAuthentication() only tries to authenticate with the default scheme and I'm guessing JWT Tokens is not your default. app.UseAuthentication()仅尝试使用默认方案进行身份验证,我猜测JWT令牌不是您的默认方案。 You can try context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme) to authenticate with jwt scheme. 您可以尝试使用context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme)来通过jwt方案进行身份验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM