新文章 网摘 文章 随笔 日记

identity中使用bearer认证在authorizationhandler中没有身份信息(干货,重要)

来源文章:https://www.it1352.com/2126617.html

本文介绍了在Identityserver4和自定义AuthorizationHandler User.Identity.isAuthenticated = false上使用客户端凭据流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用身份服务器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中作多种情况的处理。默认是使用“并且”的策略。

posted @ 2022-10-25 05:35  岭南春  阅读(176)  评论(0)    收藏  举报