.netcore grpc身份验证和授权

一、鉴权和授权(grpc专栏结束后会开启鉴权授权专栏欢迎大家关注)

  1. 权限认证这里使用IdentityServer4配合JWT进行认证
  2. 通过AddAuthentication和AddAuthorization方法进行鉴权授权注入;通过UseAuthentication和UseAuthorization启用鉴权授权
  3. 增加授权策略处理
  4. 使用密码模式,及简易内存处理
  5. 生成token带入grpc的metadata进行传递
  6. 服务端对应的方法标记特性[Authorize]进行验证
  7. 代码中会有对应的注释说明,如果对您有用,可静下心来细致的浏览

二、实战案例

  1. 需要一个授权中心服务
  2. 需要一个gRPC后端服务
  3. 需要一个客户端调用对应的授权中心和gRPC后端服务

第一步:授权中心

        1)引入IdentityServer4包

        2)添加IdentityServer注入及启用IdentityServer

// 添加IdentityServer4注入

// 注入id4服务 配置开发证书 配置内存客户端client
builder.Services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryClients(PasswordInfoConfig.GetClients())
                .AddInMemoryApiResources(PasswordInfoConfig.GetApiResources())
                .AddInMemoryApiScopes(PasswordInfoConfig.GetApiScopes())
                .AddTestUsers(PasswordInfoConfig.GetUsers());


// 启用IdentityServer 同时启用认证和授权

app.UseIdentityServer();
app.UseAuthentication();

app.UseAuthorization();

        3)密码 在程序中进行了初始化;因为是模拟,这里就没有放到数据库

    public class PasswordInfoConfig
    {

        /// 
        /// 获取设定客户端
        /// 
        /// 
        public static IEnumerable GetClients()
        {
            return new[] {
                new Client{
                    ClientId="laoliu",
                    ClientSecrets= new []{ new Secret("laoliu123456".Sha256()) },
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    AllowedScopes = new[] {"TestApi","UserApi"},
                    Claims = new List(){
                        new ClientClaim(JwtClaimTypes.Role,"Admin"),
                        new ClientClaim(JwtClaimTypes.NickName,"王先生"),
                        new ClientClaim(JwtClaimTypes.Email,"[email protected]")
                    }
                }
            };

        }

        /// 
        /// 获取Api对应的作用域
        /// 
        /// 
        public static IEnumerable GetApiScopes()
        {
            return new[] { new ApiScope("UserApi", "用户作用域"), new ApiScope("TestApi", "测试作用域") };
        }

        /// 
        /// 获取Api资源
        /// 
        /// 
        public static IEnumerable GetApiResources()
        {
            return new[]
            {
                new ApiResource("TestApi","测试的API",new List{ IdentityModel.JwtClaimTypes.Role,"email"})
                {
                    Scopes = new List { "TestApi" }
                },
                new ApiResource("UserApi","用户的API",new List{ JwtClaimTypes.NickName,"email"})
                {
                    Scopes= new List { "UserApi" }
                }
            };
        }


        public static List GetUsers()
        {
            return new List
            {
                new TestUser()
                {
                    Username="admin",
                    Password="password",
                    SubjectId="0",
                    Claims= new List(){
                        new Claim(JwtClaimTypes.Role,"Admin"),
                        new Claim(JwtClaimTypes.NickName,"陈先生"),
                        new Claim(JwtClaimTypes.Email,"77.com")
                    }
                }
            };
        }
    }

第二步:gRPC后端服务

        1)引入IdentityServer4、IdentityServer4.AccessTokenValidation、Microsoft.AspNetCore.Authentication.JwtBearer包

        2)添加IdentityServer权限解析认证

        3)启用鉴权和授权

        4)对应的类或方法中标记 [Authorize]

        4)GRPC的服务及Proto文件这里不贴上来了 有需要可以直接百度云盘下载源码查看

// 注入
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
                {
                    // 权限中心 服务地址
                    options.Authority = "http://localhost:5172";
                    options.ApiName = "TestApi";
                    options.RequireHttpsMetadata = false;
                });

builder.Services.AddAuthorization();
builder.Services.AddGrpc();

// 启用

app.UseAuthentication();
app.UseAuthorization();

// 字段
app.MapGrpcService();

// 基础配置
[Authorize]
public override async Task BaseConfigService(BaseConfig request, ServerCallContext context)
{
    await Console.Out.WriteLineAsync("\r\n--------------------------基础配置--------------------------\r\n");
    // 打印字段信息
    var properties = request.GetType().GetProperties();
    foreach (var property in properties)
    {
        var value = property.GetValue(request);

        await Console.Out.WriteLineAsync($"{property.Name}:{value}");
    }
    return new Empty();
}

第三步:WPF客户端

        1)调用鉴权中心获取token

        2)gRPC工厂中配置token传递 或者在调用对应的客户端函数中对metadata传参

        3)调用

    public class WpfAuthClient
    {
        private static string _token = null;

        public static async Task GetToken()
        {
            if (_token != null)
            {
                return _token;
            }
            var client = new HttpClient();
            PasswordTokenRequest tokenRequest = new PasswordTokenRequest();
            tokenRequest.Address = "http://localhost:5172/connect/token";
            tokenRequest.GrantType = GrantType.ResourceOwnerPassword;
            tokenRequest.ClientId = "laoliu";
            tokenRequest.ClientSecret = "laoliu123456";
            tokenRequest.Scope = "TestApi";
            tokenRequest.UserName = "admin";
            tokenRequest.Password = "password";


            var tokenResponse = await client.RequestPasswordTokenAsync(tokenRequest);

            var token = tokenResponse.AccessToken;
            var tokenType = tokenResponse.TokenType;

            _token = $"{tokenType} {token}";

            return _token;
        }
    }
    public static class GrpcClient
    {
        /// 
        /// rpc 工厂注入
        /// 
        /// 
        /// 
        public static IServiceCollection AddWPFGrpc(this IServiceCollection services)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }
            services.AddGrpcClient(options =>
            {
                options.Address = new Uri("https://localhost:7188");
            }).AddCallCredentials(async (context, metadata) =>
            {
                var token = await WpfAuthClient.GetToken();
                metadata.Add("Authorization", token);
            });

            return services;
        }
    }

三、执行效果展示

        1)启动鉴权中心

.netcore grpc身份验证和授权_第1张图片

         2) 启动gRPC后端服务

.netcore grpc身份验证和授权_第2张图片

        3)先看下不传token的结果

.netcore grpc身份验证和授权_第3张图片

         4)加入token获取传递展示

授权中心返回

.netcore grpc身份验证和授权_第4张图片

 gRPC服务展示

.netcore grpc身份验证和授权_第5张图片

 客户端返回成功

.netcore grpc身份验证和授权_第6张图片

 四、源码地址

链接:https://pan.baidu.com/s/1viu-REcR-ySdR0FE05sohg 
提取码:y0m4

你可能感兴趣的:(.netcore,rpc)