identity中使用bearer认证在authorizationhandler中没有身份信息(干货,重要)
来源文章:https://www.it1352.com/2126617.html
问题描述
我正在使用身份服务器4,我创建了一个受client_credentials保护的客户端
我能够使用clientid和secret来检索令牌,并且根据jwt.io,访问令牌的到期时间为3600秒或(1小时)
在网络核心2.2 api上,我有一个自定义AuthorizationHandler
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ClientCredentialRequirement requirement)
{
if (requirement.AllowedClients != null && requirement.AllowedClients.Any()) {
if (context.User.Identity.IsAuthenticated) { // this is false
context.Succeed(requirement);
return Task.CompletedTask;
}
使用客户端凭据时,该返回false吗?我一直期望它是真实的,因为令牌是有效的
推荐答案
所以我明白了.
事实证明,该应用程序是功能齐全的"idserver"加上已经配置了cookie身份验证的"mvc网站",这导致了我的问题.
对api的请求没有声明,因为未使用Bearer身份验证方案来处理该请求.
我必须将其添加到api控制器中才能正常工作.
[Authorize(AuthenticationSchemes = "Bearer")]
public class MixedController : Controller
详细此处
现在,即使使用客户端凭据,User.Identity声明也将使用令牌中的声明和范围进行填充,并且User显示为Authenticated = true
IdentityServer4深入使用(二)- 认证与授权(下) - 修身养性,知行合一 (jeremyjone.com)
授权 - 授权策略提供程序 - 《ASP.NET Core 3.1 微软官方教程》 - 书栈网 · BookStack
IdentityServer4 4.x版本 配置Scope的正确姿势 - xhznl - 博客园 (cnblogs.com)
IdentityServer 基于scope给接口做授权,实现多范围 - 唉我干啥啊 - 博客园 (cnblogs.com)
自己实践出来的真知:
IdentityServer4使用Bearer认证,在Mvc客户端登录后,以在http header中添加access_token的方式请求api资源,但api一直返回401未授权,也获取不到用户的username和claims,折磨了好多天,终于知道原因,注意下面红色部分:
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "ApiSample", Version = "v1" }); }); services.AddMvcCore() .AddAuthorization(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => { options.Authority = "https://localhost:44310"; options.RequireHttpsMetadata = false; options.Audience = "ApiSample"; options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" }; //下面这个很重要,因为令牌是ids4服务器颁发的,不是这个api自己颁发的, //所以options.TokenValidationParameters.ValidateAudience设置为false //否则一直返回401且无法获取claims options.TokenValidationParameters.ValidateAudience = false; }); }
应该也可以显式设置token的颁发来源来达到目的。
另外要注意:
1、mvc客户端的action里要设置[Authorize]属性,才能保证不会在未登录未获取access_token的情况下访问api
2、api的action上最好加上[Authorize(AuthenticationSchemes = "Bearer")]属性,明确表示是以jwt验证
3、最好加上options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };以兼容token
4、如果要实现“或者”的策略,请使用相同的IAuthorizationRequirement对就多个不同的hanldler,或同一个hanlder中作多种情况的处理。默认是使用“并且”的策略。
浙公网安备 33010602011771号