栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

.NET 5 GRPC 认证和授权

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

.NET 5 GRPC 认证和授权

认证和授权一般是同时出现的,先做认证,认证的时候进行权限获取,进入接口之前根据接口的权限要求进行授权校验

假设有个接口,他需要的访问权限是用户年龄必须为18岁,采用jwt进行认证

接口访问流程:用户先获取到JWT的token—>请求接口带上token—>进行token校验并将用户的年龄作为Claim设置到ClaimsPrincipal中---->进入接口权限校验

  • 先启用认证和授权,该配置一定要在app.UseEndpoints之前,认证最好也是放在授权之前,否则会先进行授权逻辑再进行验证逻辑
            // 开启验证
            app.UseAuthentication();
            //启用授权
            app.UseAuthorization();
  • 配置认证模块
 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(o =>
                {
                    o.SaveToken = true;
                    o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                    {
                        
                    };
                    o.SecurityTokenValidators.Clear();
                    o.SecurityTokenValidators.Add(new TokenValidtor());
                });

其中TokenValidtor为自定义的验证类,主要进行token的验证,并获取用户权限

    public class TokenValidtor : ISecurityTokenValidator
    {
        public bool CanValidateToken => throw new NotImplementedException();

        public int MaximumTokenSizeInBytes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public bool CanReadToken(string securityToken)
        {
            if (!string.IsNullOrEmpty(securityToken))
            {
                return true;
            }
            return false;
        }

        ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            validatedToken = null;

            var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
            identity.AddClaim(new Claim("Age", "17"));
            var principal = new ClaimsPrincipal(identity);
            return principal;
        }
    }
  • 配置授权模块
            services.AddAuthorization(options =>
            {
                options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
                {
                    policy.Requirements.Add(new PermissionRequirement { Age = 18 });
                });
            });

其中PermissionRequirement 为自定义的权限设置类,再自定义PermissionHandler,继承AuthorizationHandler ,并重写HandleRequirementAsync方法,对用户权限和接口权限进行匹配校验

 public class PermissionRequirement : IAuthorizationRequirement
    {   
        /// 
        /// 年龄
        /// 
        public int Age{ get; set; }

    }


    public class PermissionHandler : AuthorizationHandler
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            var age = context.User.Claims.First(p => p.Type.Equals("Age")).Value;
            if (age.Equals(requirement.Age.ToString()))
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
            return Task.CompletedTask;
        }
    }
  • 注册IAuthorizationHandler对应的实现类,可以使用自己的IOC框架也可以使用.net5自带的DI注册
services.AddTransient();
  • 服务端 在需要进行校验的接口方法上增加Authorize属性,该属性的参数对应授权模块注册时候AddPolicy中某一个的名称
[Authorize(JwtBearerDefaults.AuthenticationScheme)]
public override Task GetUserStatus(GetUserStatusInput request, ServerCallContext context)
  • 客户端在调用接口的时候在header增加Authorization设置
 var channel = GrpcChannel.ForAddress("http://localhost:5000");
var client = new User.UserService.UserServiceClient(channel);
var loginResult = client.Login(new User.LoginInput { Name = "huang", Password = "123456" });
var headers = new Metadata { { "Authorization", $"Bearer {loginResult.Token}" } };
var userStatus = client.GetUserStatus(new User.GetUserStatusInput { Token = loginResult.Token }, headers);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/910895.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号