调用授权方法时 JWTBearer 错误
JWTBearer error on calling authorized method
我正在为小型本机移动应用程序开发移动 REST API。
我的麻烦是 JWT 在汇编 Microsoft.AspNetCore.Authentication.JwtBearer, Version=3.0.2.0
我在 startup.cs 方法 ConfigureServices 中的设置:
services.AddAuthentication()
.AddJwtBearer(CommonHelper.MobileApiConstant.AuthSchemaName, options =>
{
options.SaveToken = true;
options.IncludeErrorDetails = true;
options.RequireHttpsMetadata = true;
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey =
new SymmetricSecurityKey(
CommonHelper.MobileApiConstant.GetSymmetricSecurityKeyByteArray(_customerCodeConfiguration.CustomerCode)),
ValidateIssuerSigningKey = false,
ValidateIssuer = false,
ValidateAudience = false,
};
});
我的 API 控制器是:
[Route(CommonHelper.MobileApiConstant.RouteName + "/[controller]/[action]")]
[ApiController]
[Authorize(AuthenticationSchemes = CommonHelper.MobileApiConstant.AuthSchemaName)]
[ApiVersion("1")]
public class AuthenticationController : Controller
{
[HttpGet]
[AllowAnonymous]
[ProducesResponseType(typeof(ResultModel<IMobileCrmUser>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Authenticate([NotNull] string userName, [NotNull] string password)
{
if (!IsOk) // some usless logic
{
return Unauthorized();
}
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
byte[] key = CommonHelper.MobileApiConstant.GetSymmetricSecurityKeyByteArray("My private string");
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(14),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
[HttpGet]
[ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public IActionResult TestMethodGet(string test)
{
if (test == nameof(test))
return Ok("succes");
else
return BadRequest("bad");
}
}
当我调用方法 Authenticate (Allow anonymous) 时一切正常:
curl -X GET "https://localhost:5001/MobileApi/Authentication/Authenticate?userName=mail%40mail.cz&password=password" -H "accept: text/plain" -H "x-api-version: 1"
令牌已返回。然后我想调用 TestMethodGet 方法请求是:
curl -X GET "https://localhost:5001/MobileApi/Authentication/TestMethodGet?test=test" -H "accept: text/plain" -H "x-api-version: 1" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImR2ZXNlbHlAY2VudHJ1bS5jeiIsIm5hbWVpZCI6IjIiLCJyb2xlIjpbIkFkbWluIiwiQnVzaW5lc3MiXSwibmJmIjoxNTg3MDMxOTAwLCJleHAiOjE1ODgyNDE1MDAsImlhdCI6MTU4NzAzMTkwMH0.rb_0nxWqedmruaBiaivd8ZrQBBi9SNcgsEQlqrOxhAo"
响应是:
content-length: 0
date: Thu, 16 Apr 2020 10:13:51 GMT
server: Kestrel
status: 401
www-authenticate: Bearer
我不知道错误在哪里,也不知道为什么服务器不给我写更多信息。 API 调用是通过 Swagger 进行的。
我尝试设置 options.IncludeErrorDetails = true;但结果相同。
感谢您的帮助
您需要在 Authorization
header 中添加单词 Bearer
:
Authorization: Bearer eyJhbGciOi..
那么应该可以了。
在回复中
content-length: 0
date: Thu, 16 Apr 2020 10:13:51 GMT
server: Kestrel
status: 401
www-authenticate: Bearer
您不仅可以看到状态,在本例中为 401,还可以看到响应 header
www-authenticate: Bearer
根据 RFC1945
告诉你使用哪个方案:
The field value consists of at
least one challenge that indicates the authentication scheme(s) and
parameters applicable to the Request-URI.
因此,在这种情况下是 Bearer
方案。
Bearer
是实现 OAuth2.0 授权协议的 standard 方案。
另见 this Q/A。
我正在为小型本机移动应用程序开发移动 REST API。 我的麻烦是 JWT 在汇编 Microsoft.AspNetCore.Authentication.JwtBearer, Version=3.0.2.0
我在 startup.cs 方法 ConfigureServices 中的设置:
services.AddAuthentication()
.AddJwtBearer(CommonHelper.MobileApiConstant.AuthSchemaName, options =>
{
options.SaveToken = true;
options.IncludeErrorDetails = true;
options.RequireHttpsMetadata = true;
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey =
new SymmetricSecurityKey(
CommonHelper.MobileApiConstant.GetSymmetricSecurityKeyByteArray(_customerCodeConfiguration.CustomerCode)),
ValidateIssuerSigningKey = false,
ValidateIssuer = false,
ValidateAudience = false,
};
});
我的 API 控制器是:
[Route(CommonHelper.MobileApiConstant.RouteName + "/[controller]/[action]")]
[ApiController]
[Authorize(AuthenticationSchemes = CommonHelper.MobileApiConstant.AuthSchemaName)]
[ApiVersion("1")]
public class AuthenticationController : Controller
{
[HttpGet]
[AllowAnonymous]
[ProducesResponseType(typeof(ResultModel<IMobileCrmUser>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Authenticate([NotNull] string userName, [NotNull] string password)
{
if (!IsOk) // some usless logic
{
return Unauthorized();
}
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
byte[] key = CommonHelper.MobileApiConstant.GetSymmetricSecurityKeyByteArray("My private string");
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(14),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(tokenHandler.WriteToken(token));
}
[HttpGet]
[ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public IActionResult TestMethodGet(string test)
{
if (test == nameof(test))
return Ok("succes");
else
return BadRequest("bad");
}
}
当我调用方法 Authenticate (Allow anonymous) 时一切正常:
curl -X GET "https://localhost:5001/MobileApi/Authentication/Authenticate?userName=mail%40mail.cz&password=password" -H "accept: text/plain" -H "x-api-version: 1"
令牌已返回。然后我想调用 TestMethodGet 方法请求是:
curl -X GET "https://localhost:5001/MobileApi/Authentication/TestMethodGet?test=test" -H "accept: text/plain" -H "x-api-version: 1" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImR2ZXNlbHlAY2VudHJ1bS5jeiIsIm5hbWVpZCI6IjIiLCJyb2xlIjpbIkFkbWluIiwiQnVzaW5lc3MiXSwibmJmIjoxNTg3MDMxOTAwLCJleHAiOjE1ODgyNDE1MDAsImlhdCI6MTU4NzAzMTkwMH0.rb_0nxWqedmruaBiaivd8ZrQBBi9SNcgsEQlqrOxhAo"
响应是:
content-length: 0
date: Thu, 16 Apr 2020 10:13:51 GMT
server: Kestrel
status: 401
www-authenticate: Bearer
我不知道错误在哪里,也不知道为什么服务器不给我写更多信息。 API 调用是通过 Swagger 进行的。
我尝试设置 options.IncludeErrorDetails = true;但结果相同。
感谢您的帮助
您需要在 Authorization
header 中添加单词 Bearer
:
Authorization: Bearer eyJhbGciOi..
那么应该可以了。
在回复中
content-length: 0
date: Thu, 16 Apr 2020 10:13:51 GMT
server: Kestrel
status: 401
www-authenticate: Bearer
您不仅可以看到状态,在本例中为 401,还可以看到响应 header
www-authenticate: Bearer
根据 RFC1945 告诉你使用哪个方案:
The field value consists of at least one challenge that indicates the authentication scheme(s) and parameters applicable to the Request-URI.
因此,在这种情况下是 Bearer
方案。
Bearer
是实现 OAuth2.0 授权协议的 standard 方案。
另见 this Q/A。