【发布时间】:2021-03-14 00:16:42
【问题描述】:
首先,感谢您花时间阅读本文。
我需要在另一个 .net core 3.1 应用程序中验证一个 .net core 2.2 应用程序生成的 JWT 令牌。
目前,我无法使用 .net 核心授权来验证令牌,但能够编写单独的方法来验证令牌。我已确保用于签署令牌的秘密是相同的。
如何使用 .net core 3.1 中的内置身份验证来验证从不同应用程序生成的令牌。
下面是详细说明:
我为登录请求创建了一个 API,该 API 使用此 tutorial 生成 JWT 令牌以在 .net core 2.2 上进行验证。
在我的登录 API 中,在 startup.cs,我添加了如下身份验证:
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
我这样生成令牌:
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, dbUser.UserID.ToString())
}),
Expires = DateTime.Now.AddMinutes(_appSettings.Expiry_Min),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
Audience = _appSettings.Audience,
Issuer = _appSettings.Issuer,
};
var token = tokenHandler.CreateToken(tokenDescriptor);
JWT 令牌效果很好。在我的控制器中,我添加了 [Authorize] 属性,带有无效令牌的请求会立即被拒绝。
现在,我想在 .net core 3.1 的另一个应用程序中验证我的登录 API 生成的令牌,以验证登录响应。为此,我参考了这个tutorial。在第二个应用程序的 startup.cs 中,我有:
private void SetupJWTServices(IServiceCollection services)
{
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
这个方法,调用如下:
public void ConfigureServices(IServiceCollection services)
{
SetupJWTServices(services);
services.AddControllers();
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
}
在我的第二个应用程序中,当我使用 [Authorize] 属性时,请求立即被 401 拒绝,未经授权。但是,当我不使用 [Authorize] 属性并创建验证令牌的方法时,该方法能够验证所有有效请求。我写的方法是:
private void Validator(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
var appSettingsSection = _appConfiguration.GetSection("AppSettings");
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
try
{
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
ClockSkew = TimeSpan.Zero
}, out SecurityToken validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
// return account id from JWT token if validation successful
}
catch
{
// return null if validation fails
}
这对我来说意味着要验证所有请求,我需要在处理任何内容之前先通过此验证器方法将其传递。但是,这没有使用内置的授权控制。好像不太对。
这是在不同应用程序之间验证 JWT 令牌的方式吗?
【问题讨论】:
-
您的意思是您可以手动验证令牌,但该令牌可用于请求受保护的端点?
-
@FeiHan 是的,我可以手动验证令牌。我无法使用 .net 核心授权。
-
我已经使用 IdentityServer4 完成了这项工作。我不认为您可以在不使用 IdentityServer4 库的情况下将您的第一个应用程序用作身份服务器。您的第一个应用程序应该像这样公开一个端点:localhost:5000/.well-known/openid-configuration,第二个应用程序应该从该端点获取配置以配置其算法/设置。
标签: c# asp.net-core authentication jwt