ASP.NET Core 3.1 MVC JWT 登录返回 401
Posted
技术标签:
【中文标题】ASP.NET Core 3.1 MVC JWT 登录返回 401【英文标题】:ASP.NET Core 3.1 MVC JWT Login return 401 【发布时间】:2021-11-01 15:18:18 【问题描述】:我有一个问题,jwt 认证返回 401 错误。 令牌已创建但总是返回 401 错误。
我使用了分层架构。我在 startup.cs 上尝试了很多东西。 JWT 和 startup.cs 代码在下面。如果您想查看其他代码,将会更新。
JwtHelper 代码:
public class JwtHelper : ITokenHelper
public IConfiguration Configuration get;
private TokenOptions _tokenOptions;
private DateTime _accessTokenExpiration;
public JwtHelper(IConfiguration configuration)
Configuration = configuration;
_tokenOptions = Configuration.GetSection("TokenOptions").Get<TokenOptions>();
public AccessToken CreateToken(User user, List<OperationClaim> operationClaims)
_accessTokenExpiration = DateTime.Now.AddMinutes(_tokenOptions.AccessTokenExpiration);
var securityKey = SecurityKeyHelper.CreateSecurityKey(_tokenOptions.SecurityKey);
var signingCredentials = SigningCredentialsHelper.CreateSigningCredentials(securityKey);
var jwt = CreateJwtSecurityToken(_tokenOptions, user, signingCredentials, operationClaims);
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
var token = jwtSecurityTokenHandler.WriteToken(jwt);
return new AccessToken
Token = token,
Expiration = _accessTokenExpiration
;
public JwtSecurityToken CreateJwtSecurityToken(TokenOptions tokenOptions, User user,
SigningCredentials signingCredentials, List<OperationClaim> operationClaims)
var jwt = new JwtSecurityToken(
issuer: tokenOptions.Issuer,
audience: tokenOptions.Audience,
expires: _accessTokenExpiration,
notBefore: DateTime.Now,
claims: SetClaims(user, operationClaims),
signingCredentials: signingCredentials
);
return jwt;
private IEnumerable<Claim> SetClaims(User user, List<OperationClaim> operationClaims)
var claims = new List<Claim>();
claims.AddNameIdentifier(user.id.ToString());
claims.AddEmail(user.Email);
claims.AddName($"user.FirstName user.LastName");
claims.AddRoles(operationClaims.Select(c => c.name).ToArray());
return claims;
Statup.cs
public void ConfigureServices(IServiceCollection services)
services.AddCors();
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
services.AddControllersWithViews();
services.AddRazorPages();
var tokenOptions = Configuration.GetSection("TokenOptions").Get<TokenOptions>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = tokenOptions.Issuer,
ValidAudience = tokenOptions.Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey)
;
);
services.AddControllersWithViews();
services.AddDependencyResolvers(new ICoreModule[]
new CoreModule()
);
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(o =>
o.LoginPath = "/Auth/Login";
);
// 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
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseCors(builder => builder.WithOrigins("https://localhost:44378").AllowAnyHeader());
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
endpoints.MapControllerRoute(
name: "default",
pattern: "controller=Customer/action=Index/id?");
);
app.UseStatusCodePages();
我已经搜索了 1 周,但没有找到。
【问题讨论】:
查看编译器警告。app.UseAuthentication
需要之前 app.UseAuthorization
。这只是一个问题,可能还有更多。
@CamiloTerevinto 不幸的是它没有用。 :(
【参考方案1】:
当你注册 JwtToken 处理程序后,这个
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(o =>
o.LoginPath = "/Auth/Login";
将您的默认身份验证方案设为 CookieAuthenticationDefaults.AuthenticationScheme
,它使用 cookie 作为验证。
代码应该是
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme, opts =>
opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = tokenOptions.Issuer,
ValidAudience = tokenOptions.Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey)
;
)
.AddCookie(o =>
o.LoginPath = "/Auth/Login";
);;
正如@Camilo Terevinto 所说,app.UseAuthentication
必须在 app.UseAuthorization
之前。
【讨论】:
视图重定向与身份验证完全不同的概念,请随意应用您自己的逻辑以上是关于ASP.NET Core 3.1 MVC JWT 登录返回 401的主要内容,如果未能解决你的问题,请参考以下文章
使用两个 JWT 身份验证方案,ASP.NET Core 3.1
ASP.Net Core - 使用 WebAPI 和 MVC 前端的 JWT 身份验证不起作用
JWT 身份验证 ASP.NET Core MVC 应用程序
使用 ADFS 的 JWT Bearer 身份验证将 ASP.NET Framework 迁移到 ASP.NET Core 3.1