[英]JWT Token generates but does not Authenticate (401)
我正在尝试按照此指南链接将 JWT 身份验证添加到我的应用程序
令牌生成正确(在 JWT.io 上测试)但是当调用 API 中的方法时,我只得到 401。
我正在使用 Swagger 拨打电话(我也尝试过 postman)
启动.cs
private void AddSwagger(IServiceCollection services)
{
services.AddSwaggerGen(x => {
x.SwaggerDoc("v1", new Info { Title = ApiDescription, Version = "v1" });
var xmlDocFile = Path.Combine(AppContext.BaseDirectory, $"{_hostingEnvironment.ApplicationName}.xml");
if (File.Exists(xmlDocFile))
{
var comments = new XPathDocument(xmlDocFile);
x.OperationFilter<XmlCommentsOperationFilter>(comments);
x.SchemaFilter<XmlCommentsSchemaFilter>(comments);
}
x.AddSecurityDefinition("Bearer", new ApiKeyScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = "header",
Type = "apiKey"
});
x.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "Bearer", new string[] { } }
});
x.OperationFilter<SecurityRequirementsOperationFilter>();
});
}
private void AddJWT(IServiceCollection services)
{
var key = Encoding.ASCII.GetBytes(ConfigurationRoot["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 Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseCors("Fintrans");
app.UseAuthentication();
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(x => { x.SwaggerEndpoint(ConfigurationRoot["Swagger:Path"], ApiDescription); });
applicationLifetime.ApplicationStopped.Register(() => Container.Dispose());
}
AuthController.cs
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly IAuthService _authService;
public AuthController(IAuthService authService)
{
_authService = authService;
}
[AllowAnonymous]
[HttpPost]
public LoginResponse Login(LoginRequest request)
{
return _authService.Login(request) as LoginResponse;
}
[HttpGet]
public IActionResult GetAll()
{
return Ok();
}
}
身份验证服务.cs
public class AuthService : IAuthService
{
private readonly AppSettings _appSettings;
public AuthService(AppSettings appSettings)
{
_appSettings = appSettings;
}
public ILoginResponse Login(ILoginRequest request)
{
try
{
User user = InMemoryData.Users.Find(o =>
o.UserName == request.UserName && o.Password == request.Password);
if (user == null)
{
throw new SystemException("User or Password is Incorrect");
}
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName)
//Add roles or something here, idk
}),
Expires = DateTime.UtcNow.AddMinutes(150),
IssuedAt = DateTime.UtcNow,
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(_appSettings.Secret), SecurityAlgorithms.HmacSha256Signature)
};
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
return new LoginResponse()
{
Exception = null,
Token = tokenHandler.WriteToken(token),
ResponseDateTime = DateTime.Now,
IsSuccessful = true
};
}
catch (Exception exception)
{
return new LoginResponse()
{
Exception = exception,
IsSuccessful = false,
ResponseDateTime = DateTime.Now,
Token = null
};
}
}
}
编辑 1 09:20 2019/11/22
任何帮助或参考都会令人惊叹,并得到我永远的钦佩,我可能会也可能不会以你的名字命名我的长子。
编辑 2 09:52 2019/11/22
在PostMan试了一下,还是401,检查了实际创建token和bearer认证时使用的key是同一个字节arrays。
Output 来自请求
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/Auth
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "GetAll", controller = "Auth"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult GetAll() on controller Sybrin.InstantPayments.Service.Auth.Controllers.AuthController (Sybrin.InstantPayments.Service.Auth).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (Bearer).
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Sybrin.InstantPayments.Service.Auth.Controllers.AuthController.GetAll (Sybrin.InstantPayments.Service.Auth) in 27.8828ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 37.4312ms 401
Failed to load resource: the server responded with a status of 401 (Unauthorized) [http://localhost:5000/api/Auth]
所以它确实在 Postman 中工作,不知道为什么它不能更早工作,电脑很奇怪。
应将问题标记为删除,因为它在技术上不能帮助任何人解决未来的问题
我在 Swagger 身份验证方面也遇到了一些问题。 请务必在 Bearer 和 token 之间输入一个空格。
承载 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.