使用ASP.NET Identity 3.0的ASP.NET Core 5,我正在使用网页和apis。我正在使用OpenIddict发出JWT令牌并进行身份验证。我的代码看起来像这样:
X509Certificate2 c = new X509Certificate2(@"tokensign.p12", "MyCertificatePassword");
services.AddOpenIddict<WebUser, IdentityRole<int>, WebDbContext, int>()
.EnableTokenEndpoint("/api/customauth/login")
.AllowPasswordFlow()
.UseJsonWebTokens()
.AddSigningCertificate(c);
如果禁用UseJsonWebTokens(),我可以生成令牌并成功授权。但是,我不确定我的证书是否验证了返回的令牌。
当启用UseJsonWebTokens时,我能够在此终点发出JWT令牌。但是,我无法验证任何请求!
我在应用配置中使用以下代码:
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
Authority = "http://localhost:60000/",
Audience = "http://localhost:60000/",
});
app.UseOAuthValidation();
app.UseIdentity();
app.UseOpenIddict();
app.UseMvcWithDefaultRoute();
答案 0 :(得分:5)
如果禁用UseJsonWebTokens(),我可以生成令牌并成功授权。但是,我不确定我的证书是否验证了返回的令牌。
在ASOS(OpenIddict背后的OpenID Connect服务器框架)中,有2种不同的内置序列化机制来创建和保护令牌:
始终使用此过程创建标识令牌(根据定义为JWT),您可以调用UseJsonWebTokens()
强制OpenIddict发出使用相同序列化过程的访问令牌。
您在调用AddSigningCertificate()
时指定的证书始终用于签署这些令牌。
此堆栈专门生成“专有”令牌,这些令牌不打算由第三方读取或验证,因为令牌格式不是标准格式,必然依赖于对称签名和加密。 / p>
这是我们用于授权代码和刷新令牌的机制,仅供OpenIddict本身使用。当您使用默认令牌格式时,它也用于访问令牌。
在这种情况下,不使用您在调用AddSigningCertificate()
时指定的证书。
相反,这些令牌始终由数据保护堆栈使用Authenticated Encryption
算法(默认情况下为AES-256-CBC和HMACSHA256)加密,提供真实性,完整性和机密性。为此,2个密钥(一个用于加密,一个用于验证)由数据保护堆栈从存储在密钥环中的一个主密钥导出。
如何强制使用我的证书验证请求,以确保JWT令牌未被篡改。 什么是允许验证和授权我的JWT令牌的正确设置,因为如果我没有使用JWT,我将获得成功授权。
要回答这些问题,如果您启用了日志记录并共享了跟踪,这将有所帮助。
答案 1 :(得分:0)
在ASP.NET Core中创建基于JWT令牌的身份验证非常简单。请点击以下链接,您将获得更多的想法。 How to Create JWT Token in Asp NET Core
示例代码
public static class AuthenticationConfig
{
public static string GenerateJSONWebToken(string user)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("730F046B1ADF1555FF0C80149B47B38CD7C0A146AAFA34870E863CAA25B585C3"));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[] {
new Claim("UserName", user),
new Claim("Role", "1"),
};
var token = new JwtSecurityToken("http://localhost:30972",
"http://localhost:30972",
claims,
DateTime.UtcNow,
expires: DateTime.Now.AddMinutes(10),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
//ConfigureJwtAuthentication
internal static TokenValidationParameters tokenValidationParams;
public static void ConfigureJwtAuthentication(this IServiceCollection services)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("730F046B1ADF1555FF0C80149B47B38CD7C0A146AAFA34870E863CAA25B585C3"));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
tokenValidationParams = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidIssuer = "http://localhost:30972",
ValidateLifetime = true,
ValidAudience = "http://localhost:30972",
ValidateAudience = true,
RequireSignedTokens = true,
// Use our signing credentials key here
// optionally we can inject an RSA key as
//IssuerSigningKey = new RsaSecurityKey(rsaParams),
IssuerSigningKey = credentials.Key,
ClockSkew = TimeSpan.FromMinutes(10)
};
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = tokenValidationParams;
#if PROD || UAT
options.IncludeErrorDetails = false;
#elif DEBUG
options.RequireHttpsMetadata = false;
#endif
});
}
}
在Startup.cs中添加此行
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureJwtAuthentication();
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
在身份验证控制器中添加这些行
[Route("api/[controller]")]
public class AuthenticationController : Controller
{
// GET: api/<controller>
[HttpGet]
public string Get(string user, string pass)
{
if (user == "admin")
{
return AuthenticationConfig.GenerateJSONWebToken(user);
}
else
{
return "";
}
}
// POST api/<controller>
[Authorize]
[HttpPost]
public string Post()
{
var identity = HttpContext.User.Identity as ClaimsIdentity;
IEnumerable<Claim> claim = identity.Claims;
var UserName = claim.Where(c => c.Type == "UserName").Select(c => c.Value).SingleOrDefault();
return "Welcome to " + UserName + "!";
}
}