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

时间:2019-09-13 10:40:06

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

我想将一些基于身份验证的用户的应用程序上下文注入到执行上下文中,以便业务/服务层可以透明地使用它。我打算使用中间件进行设置。启动时的示例代码为

app.UseAuthentication();

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

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

app.UseMvc(..)

不幸的是,在我的自定义中间件中,HttpContext.User.Identity.IsAuthenticated仍然为false。命中MVC授权过滤器时,将触发基于JWT令牌的实际身份验证。那么我该如何克服这个问题呢?有没有办法知道实际的身份验证阶段何时完成(类似于经典ASP.NET管道中的global.asax),或者如何在中间件中强制实施身份验证处理程序。我尝试使用扩展方法context.AuthenticateAsync来强制构建实际的用户主体,但徒劳无功。

我遇到的另一个问题是应用程序上下文的载体。我之前选择了AsycLocal<T>,但是发现我在中间件中设置的内容在下游代码中不可用。因此,目前,我正在使用HttpContext.Items承载可以正常运行的应用程序上下文,但我很想知道为什么AsycLocal<T>失败。是否可以保证不能在ASP.NET管道中的执行上下文中携带?

根据要求,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);

还发现需要在策略中添加方案以使多个方案起作用

        // 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));
        })

最后,在我的中间件中,我试图使用诸如

     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

1 个答案:

答案 0 :(得分:1)

XMPPTCPConnection.setUseStreamManagementResumptionDefault(true); XMPPTCPConnection.setUseStreamManagementDefault(true); final SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, null, new SecureRandom()); final XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder(); config.setXmppDomain("gcm.googleapis.com"); config.setHost("fcm-xmpp.googleapis.com"); config.setPort(5236); config.setSendPresence(false); config.setSecurityMode(SecurityMode.ifpossible); config.setDebuggerEnabled(false); config.setCompressionEnabled(true); config.setSocketFactory(sslContext.getSocketFactory()); config.setCustomSSLContext(sslContext); // Create the connection connection = new XMPPTCPConnection(config.build()); // Connect connection.connect(); // For enabling automatic re-connection ReconnectionManager.getInstanceFor(connection).enableAutomaticReconnection(); // Disable Roster at login Roster.getInstanceFor(connection).setRosterLoadedAtLogin(false); // Security checks SASLAuthentication.unBlacklistSASLMechanism("PLAIN"); SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5"); connection.login(username, apiKey); 仅尝试使用默认方案进行身份验证,我猜测JWT令牌不是您的默认方案。您可以尝试app.UseAuthentication()通过jwt方案进行身份验证。