在 Owin 上使用 JWT 通过 RSA 进行身份验证

Authenticating with RSA using JWT on Owin

使用 Owin 中间件在我的 Web API2 中考虑这段代码:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        ConfigureAuthentication(app);
        app.UseCors(CorsOptions.AllowAll);
        WebApiConfig.Register(config);
        app.UseWebApi(config);
        config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;    
    }

    private static void ConfigureAuthentication(IAppBuilder app)
    {
        var issuer = "<<MyIssuer>>";
        var audience = "<<MyAudience>>";

        const string publicKeyBase64 = "<<MyPublicKeyBase64>>";

        var certificate = new X509Certificate2(Convert.FromBase64String(publicKeyBase64));

        app.UseJwtBearerAuthentication(
            new JwtBearerAuthenticationOptions
            {
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
                AllowedAudiences = new[] { audience },
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                  new X509CertificateSecurityTokenProvider(issuer, certificate),
                }
            }
        );
    }
}

我可以从我的 IDP 获取 Bearer 令牌并在 jwt.io 中对其进行测试,结果如下:

Issuer 从代码到验证令牌的匹配项。

ClientId 从代码匹配到已验证的令牌 (sub)。

Audience 从代码到验证令牌的匹配项。

出于某种原因 - 然而,令牌在每次请求时都被拒绝(401 未经授权),我只是无法理解为什么。我的请求包括 Authorization header 以及我可以使用 jwt.io (Bearer ey..) 验证的相同不记名令牌。如果它有什么不同,我使用 Auth0。我还可以提到我已经尝试下载 public 证书并使用该文件,而不是仅使用具有相同结果的 public 密钥字符串。

设置 JwtBearerAuthenticationOptions 实例的 TokenValidationParameters 属性 有助于解决问题:

private static void ConfigureAuthentication(IAppBuilder app)
{
    var issuer = "<<MyIssuer>>";
    var audience = "<<MyAudience>>";

    const string publicKeyBase64 = "<<MyPublicKeyBase64>>";

    var certificate = new X509Certificate2(Convert.FromBase64String(publicKeyBase64));

    app.UseJwtBearerAuthentication(
        new JwtBearerAuthenticationOptions
        {
            AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
            AllowedAudiences = new[] { audience },
            IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
            {
              new X509CertificateSecurityTokenProvider(issuer, certificate),
            },
            TokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningKeyResolver = (a, b, c, d) => new X509SecurityKey(certificate),
                ValidAudience = audience,
                ValidIssuer = issuer
            }           
        }
    );
}