为什么我们要在 ConfigureServices 中的 AddJwtBearer 中以及在 asp.net 核心中创建新的 JwtSecurityToken 时提供发行者、受众和密钥
why should we provide issuer, audience and key in both AddJwtBearer in ConfigureServices and while creating new JwtSecurityToken in asp.net core
我是 JWT 身份验证 的新手。我正在 repo 中使用这个演示解决方案进行练习。我了解代码如何流动并能够使其工作。但是有个问题一直困扰着我。为什么我们要在两个地方都提供密钥、发行者和受众?
ConfigureServices
- Startup
:
services
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "http://localhost:44348",
ValidAudience = "http://localhost:44348",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"))
};
});
AuthController
中的令牌创建代码:
private JwtSecurityToken GenerateToken(IEnumerable<Claim> claims)
{
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken(
issuer: "http://localhost:44348",
audience: "http://localhost:44348",
claims: claims,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: signinCredentials
);
return tokeOptions;
}
如果我们注意到,我们可以在两个地方看到密钥、发行者和观众。据我所知,我们正在做的是因为配置或设置?我认为我们应该只在 ConfigureServices
提供这些配置。如果我错了,请纠正我,并帮助我解释为什么我们在两个地方这样做。
Why should we provide key, issuer and audience at both places?
您不必这样做。只需在需要时注入命名的 JwtBearerOptions
即可。例如,将 AuthController
更改为接受 IOptionsSnapshot<JwtBearerOptions
:
public class AuthController : ControllerBase
{
private static readonly Dictionary<string, string> _userTokens = new Dictionary<string, string> { { "abdul", null } };
private readonly JwtBearerOptions jwtOpts;
public AuthController(IOptionsSnapshot<JwtBearerOptions> jwtOpts)
{
this.jwtOpts = jwtOpts.Get(JwtBearerDefaults.AuthenticationScheme) ?? throw new Exception("JwtBearerOptions is null!");
}
private JwtSecurityToken GenerateToken(IEnumerable<Claim> claims)
{
var key = this.jwtOpts.TokenValidationParameters.IssuerSigningKey;
var signCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken(
issuer: jwtOpts.TokenValidationParameters.ValidIssuer,
audience: jwtOpts.TokenValidationParameters.ValidAudience,
claims: claims,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: signCredentials
);
return tokeOptions;
}
...
我是 JWT 身份验证 的新手。我正在 repo 中使用这个演示解决方案进行练习。我了解代码如何流动并能够使其工作。但是有个问题一直困扰着我。为什么我们要在两个地方都提供密钥、发行者和受众?
ConfigureServices
- Startup
:
services
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "http://localhost:44348",
ValidAudience = "http://localhost:44348",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"))
};
});
AuthController
中的令牌创建代码:
private JwtSecurityToken GenerateToken(IEnumerable<Claim> claims)
{
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken(
issuer: "http://localhost:44348",
audience: "http://localhost:44348",
claims: claims,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: signinCredentials
);
return tokeOptions;
}
如果我们注意到,我们可以在两个地方看到密钥、发行者和观众。据我所知,我们正在做的是因为配置或设置?我认为我们应该只在 ConfigureServices
提供这些配置。如果我错了,请纠正我,并帮助我解释为什么我们在两个地方这样做。
Why should we provide key, issuer and audience at both places?
您不必这样做。只需在需要时注入命名的 JwtBearerOptions
即可。例如,将 AuthController
更改为接受 IOptionsSnapshot<JwtBearerOptions
:
public class AuthController : ControllerBase
{
private static readonly Dictionary<string, string> _userTokens = new Dictionary<string, string> { { "abdul", null } };
private readonly JwtBearerOptions jwtOpts;
public AuthController(IOptionsSnapshot<JwtBearerOptions> jwtOpts)
{
this.jwtOpts = jwtOpts.Get(JwtBearerDefaults.AuthenticationScheme) ?? throw new Exception("JwtBearerOptions is null!");
}
private JwtSecurityToken GenerateToken(IEnumerable<Claim> claims)
{
var key = this.jwtOpts.TokenValidationParameters.IssuerSigningKey;
var signCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken(
issuer: jwtOpts.TokenValidationParameters.ValidIssuer,
audience: jwtOpts.TokenValidationParameters.ValidAudience,
claims: claims,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: signCredentials
);
return tokeOptions;
}
...