lea*_*nus 1 .net c# api core jwt
我有一个 ASP .NET Core web api,我生成了一个 JWT 令牌用于授权目的,但是每当我发出请求时,我都会收到401 - Unauthorized。
操作顺序:
1. GET for token
2. GET for user <-- 401
Run Code Online (Sandbox Code Playgroud)
我在 jwt.io 上检查了我的令牌,它是正确的。 当我删除[Authorize] attrivute 时一切正常
启动文件
public void ConfigureServices(IServiceCollection services)
{
IdentityModelEventSource.ShowPII = true;
var appSettingsSection = Configuration.GetSection("Jwt");
services.Configure<JwtSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<JwtSettings>();
services.AddControllers();
services.AddOptions();
services.AddAuthentication(x =>
{
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x=>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = appSettings.Issuer,
ValidIssuer = appSettings.Issuer,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Key))
};
}
);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Run Code Online (Sandbox Code Playgroud)
CreateToken 方法
public JwtDto CreateToken(string email, string role)
{
var now = DateTime.UtcNow;
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub,email),
new Claim(ClaimTypes.Role, role),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat,now.ToTimestamp().ToString(),ClaimValueTypes.Integer64)
};
var expires = now.AddMinutes(360);
var singingCredentails = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.Key)),SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: _settings.Issuer,
claims: claims,
notBefore: now,
expires: expires,
signingCredentials: singingCredentails
);
var token = new JwtSecurityTokenHandler().WriteToken(jwt);
return new JwtDto
{
Token = token,
Expiry = expires.ToTimestamp()
};
}
Run Code Online (Sandbox Code Playgroud)
获取令牌 - API
[HttpGet]
[Route("token")]
public IActionResult GetToken()
{
var token = _jwtHandler.CreateToken("test", "user");
return Json(token);
}
Run Code Online (Sandbox Code Playgroud)
GetUser - API <---------- 401 错误
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet("{email}")]
public async Task<UserDto> Get(string email)
{
return await _userService.GetUserAsync(email);
}
Run Code Online (Sandbox Code Playgroud)
我遇到了完全相同的问题,并认为问题出在 Startup.cs 中的 Configure() 方法中。您有正确的 UseAuthentication() 和 UseAuthorization() 调用,顺序正确,这很重要,也是我发现的问题。因此,对您而言,我认为问题在于缺少 UseCors() 调用。我的工作启动课程如下:
public class Startup
{
private bool _isDevelopmentEnvironment = true;
public IConfiguration configuration { get; }
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// Retrieve App Settings:
var appSettingsSection = configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<AppSettings>();
// Configure JWT:
var key = Encoding.ASCII.GetBytes(appSettings.JwtSharedSecret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = !_isDevelopmentEnvironment;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = appSettings.JwtValidateIssuer,
ValidateAudience = appSettings.JwtValidateAudience,
ValidateLifetime = appSettings.JwtValidateLifetime,
ClockSkew = TimeSpan.Zero
};
});
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<IHydrator<User, UserModel>, UserModelHydrator>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
_isDevelopmentEnvironment = false;
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
// TODO: Adjust CORS settings appropriately
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Run Code Online (Sandbox Code Playgroud)
我还确认令牌生成代码和 Startup.cs 代码使用应用程序设置中的相同密钥,我看不出你是如何在 CreateToken() 方法中获得它的,但我假设它来自相同的设置文件。希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
2087 次 |
| 最近记录: |