资源服务器中的 OwinMiddleware 实现抑制令牌验证

OwinMiddleware implementation in Resource Server suppresses Token validation

我已经设置了我的资源服务器 (Web Api 2) 来验证传入请求的 JWT 令牌。 JWT 令牌由 Auth0 颁发,我的客户端将其传递到我的网站 api。如果 Issuer、Audience 或 Expiry date 无效,这一切都可以正常工作并引发 401 响应。当我添加从 OwinMiddleware 派生的自定义中间件时,它会抑制令牌验证逻辑,并且我会收到 200 条针对无效请求的响应。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
         var issuer = "my issuer";
         var audience= "my audience";
         var clientId= "my client id";
         app.UseActiveDirectoryFederationServicesBearerAuthentication(
            new ActiveDirectoryFederationServicesBearerAuthenticationOptions
            {
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = audience,
                    ValidIssuer = issuer,
                    IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => parameters.IssuerSigningTokens.FirstOrDefault()?.SecurityKeys?.FirstOrDefault()
                },
                // Setting the MetadataEndpoint so the middleware can download the RS256 certificate
                MetadataEndpoint = $"{issuer.TrimEnd('/')}/wsfed/{clientId}/FederationMetadata/2007-06/FederationMetadata.xml"
            });



        HttpConfiguration config = new HttpConfiguration();

        app.Use<HttpUsernameInjector>();

        // Web API routes
        config.MapHttpAttributeRoutes();
        app.UseWebApi(config);
    }
}

和我的自定义 OwinMiddleWare:

public class HttpUsernameInjector : OwinMiddleware
{
    public HttpUsernameInjector(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        const string usernameClaimKey = "my username claim key";

        var bearerString = context.Request.Headers["Authorization"];
        if (bearerString != null && bearerString.StartsWith("Bearer ", StringComparison.InvariantCultureIgnoreCase))
        {
            var tokenString = bearerString.Substring(7);

            var token = new JwtSecurityToken(tokenString);
            var claims = token.Claims.ToList();
            var username = claims.FirstOrDefault(x => x.Type == usernameClaimKey);

            if (username == null) throw new Exception("Token should have username");

            // Add to HttpContext
            var genericPrincipal = new GenericPrincipal(new GenericIdentity(username.Value), new string[] { });

            IPrincipal principal = genericPrincipal;

            context.Request.User = principal;
        }

        await Next.Invoke(context);
    }
}

我应该如何配置自定义中间件以避免 conflict/suppressing OWIN 令牌身份验证逻辑?

OWINMiddleware 没有问题,但分配 context.Request.User 会导致问题。此处创建的 GenericIdentity 具有等于 true 的只读 IsAuthenticated,无法设置为 false。分配 context.Request.User = genericPrincipal; 时,它会用 genericPrincipal 中的 IsAuthenticated 覆盖 context.Request.User 中的 IsAuthenticated。需要在 Invoke 方法的开头检查身份验证结果,如果用户未通过身份验证则跳过该逻辑。所以它不会在 context.Request.User 中改变 IsAuthenticated

public override async Task Invoke(IOwinContext context)
    {
        if (context.Authentication.User.Identity.IsAuthenticated)
        {
            //my username injection logic
        }
        await Next.Invoke(context);
    }