我有一个使用.NET核心3.1版的项目,我正在使用令牌登录。当使用Postman进行测试时,一切都运行得很好,它创建了token,我可以用它来访问主页。
问题是,当我开始在客户端测试时,它不工作。我登录后调试并看到,令牌已经生成,但由于[Authorize]属性的原因,我无法访问HomeController。
这是我生成令牌的代码:
public async Task<HttpResponse<LoginResult>> GetTokenAsync(LoginRequest loginInfo)
{
var audience = await _audiences.FindAsync(a => a.Id == loginInfo.ClientId);
string message = string.Empty;
if (audience != null)
{
bool audienceIsValid = _jwtProvider.ValidateAudience(audience.Issuer
, audience.SecretKey
, ref message);
if (audienceIsValid)
return await GenerateToken(loginInfo);
else
message = ErrorMessages.Login_AudienceInvalid;
}
else
message = string.Format(ErrorMessages.Login_Not_Permitted, "Your client Id");
return HttpResponse<LoginResult>.Error(message, HttpStatusCode.BadRequest);
}我猜该令牌不能正确存储。
我遗漏了什么?
更新这是我在登录时的代码
[HttpPost]
[Route("login")]
[AllowAnonymous]
public async Task<ActionResult> Login([FromForm]LoginRequest model)
{
model.ClientId = 1;
var response = await _services.GetTokenAsync(model);
if (response.StatusCode == 200)
{
return RedirectToAction("Index", "Home");
}
return RedirectToAction("Login");
}这就是我想要访问的
[HttpGet]
[Route("index")]
[Authorize]
public IActionResult Index()
{
return View();
}发布于 2020-04-01 00:53:55
您需要创建一个自定义策略,以在Authorize属性中指定,该属性配置为使用自定义需求处理程序
首先,通过继承IAuthorizationRequirement的类展示定制策略的需求
public class TokenRequirement : IAuthorizationRequirement
{
}在这里,如果您需要参数,您可以选择接受它们。但通常情况下,您在请求的头部传递一个令牌,您的自定义策略的需求处理程序无需显式参数即可访问该令牌。
您的自定义策略将使用的需求处理程序如下所示
public class TokenHandler : AuthorizationHandler<TokenRequirement>
{
//Some kind of token validator logic injected into your handler via DI
private readonly TokenValidator _tokenValidator;
//The http context of this request session also injected via DI
private readonly IHttpContextAccessor _httpCtx;
//The name of the header your token can be found under on a Http Request
private const string tokenHeaderKey = "authToken";
//Constructor using DI to get a instance of a TokenValidator class you would
//have written yourself, and the httpContext
public TokenHandler(TokenValidator tokenValidator, IHttpContextAccessor httpCtx)
{
_tokenValidator = tokenValidator;
_httpCtx = httpCtx;
}
//Overriden implementation of base class AuthorizationHandler's HandleRequirementAsync method
//This is where you check your token.
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context
,TokenRequirement requirement)
{
if (context.Resource is Endpoint endpoint)
{
HttpRequest httpReqCtx = _httpCtx.HttpContext.Request;
string token =
httpReqCtx.Headers.TryGetValue(tokenHeaderKey, out StringValues tokenVal)
? tokenVal.FirstOrDefault()
: null;
if (string.IsNullOrWhitespace(token))
{
context.Fail();
}
else
{
bool tokenIsValid = await _tokenValidator.ValidToken(token);
if(tokenIsValid)
context.Succeed(requirement);
else
context.Fail();
}
}
return Task.CompletedTask;
}
}您可以在Startup.cs中的自定义策略名称上注册您的自定义需求处理程序,如下所示
//This is a framework extension method under Microsoft.Extensions.DependencyInjection
services.AddHttpContextAccessor();
//Your custom handler
services.AddSingleton<IAuthorizationHandler, TokenHandler>();
//Your custom policy
services.AddAuthorization(options =>
{
options.AddPolicy(
//Your custom policy's name, can be whatever you want
"myCustomTokenCheckerPolicy",
//The requirement your policy is going to check
//Which will be handled by the req handler added above
policy => policy.Requirements.Add(new TokenRequirement())
);
});该属性的impl将如下所示
[HttpGet]
[Route("index")]
[Authorize(Policy = "myCustomTokenCheckerPolicy")]
public IActionResult Index()
{
return View();
}https://stackoverflow.com/questions/60953361
复制相似问题