在 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
}
}
);
}
使用 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
}
}
);
}