.Net Core gRPC入门(四)——身份认证

本文详细指导了如何在gRPC服务端实现身份认证,包括添加Nuget包、配置JwtBearer身份验证、编写Proto文件、服务实现及授权,并提供了客户端获取Token的示例。通过一步步操作,帮助读者理解gRPC中身份验证的核心步骤和实践技巧。
摘要由CSDN通过智能技术生成

身份认证用于登陆认证、授权等作用,下面将展示如何在gRPC中进行身份认证

一、服务端添加身份认证


1. 添加Nuget包

工具 > Nuget包管理器 > 程序包管理控制台 > 设置默认项目为GrpcDemo.Service

输入以下命令

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -v 3.1.14

2. 添加身份认证

修改 GrpcDemo.Service > Startup.cs

public void ConfigureServices(IServiceCollection services)
{
	//注册身份认证服务
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    //使用Jwt认证
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidIssuer = "jwttest",
            ValidAudience = "jwttest",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("hello_worldhello_worldhello_worldhello_world")),
        };
    });
	//注册授权服务
    services.AddAuthorization();
    //...省略
}

3. 添加Proto文件

在 GrpcDemo.Service\Protos 添加一个proto文件,命名为auth.proto

添加以下内容:

syntax = "proto3";

option csharp_namespace = "GrpcDemo.Service";

package auth;

// The greeting service definition.
service Auth {
  // Sends a greeting
  rpc GetToken (AuthData) returns (AuthResult);
  rpc Test(Empty) returns (Empty);
}

// The request message containing the user's name.
message AuthData {
  string name = 1;
  string pass = 2;
}

// The response message containing the greetings.
message AuthResult {
  int32 code = 1;
  string token = 2;
  string message = 3;
}

message Empty{}

该文件声明了一个Auth服务,包含GetToken、Test方法以及传输对象数据结构。


修改GrpcDemo.Service项目文件:

<!-- 将 greet.proto 替换为 *.proto -->
<Protobuf Include="Protos\*.proto" GrpcServices="Server" />

注意:在添加proto文件后,客户端需重新生成项目,生成proto声明的类


4. 添加服务实现

在 GrpcDemo.Service\Services 添加AuthService.cs类,继承于生成的Auth.AuthBase

添加以下内容:

//重写GetToken编写认证逻辑
public override Task<AuthResult> GetToken(AuthData request, ServerCallContext context)
{
    if (request.Name == "alice" && request.Pass == "alice")
    {
        var claims = new[] {
            new Claim(ClaimTypes.Name, "alice"),
            new Claim(ClaimTypes.NameIdentifier, "0")
        };
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("hello_worldhello_worldhello_worldhello_world"));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var token = new JwtSecurityToken(
            issuer: "jwttest",
            audience: "jwttest",
            claims: claims,
            notBefore: DateTime.UtcNow,
            expires: DateTime.UtcNow.AddSeconds(10),
            signingCredentials: creds);
        var stoken = new JwtSecurityTokenHandler().WriteToken(token);
        return Task.FromResult(new AuthResult()
        {
            Code = 1,
            Message = "success",
            Token = stoken
        });
    }
    return Task.FromResult(new AuthResult()
    {
        Code = -1,
        Message = "用户名或密码错误"
    });
}

//添加Authorize测试认证
[Authorize]
public override Task<Empty> Test(Empty request, ServerCallContext context)
{
    var user = context.GetHttpContext().User;
    Console.WriteLine(user.Identity.Name);
    return Task.FromResult(new Empty());
}

5. 注册授权服务并添加认证

修改 GrpcDemo.Service > Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    //注册身份认证服务
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    //使用Jwt认证
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidIssuer = "jwttest",
            ValidAudience = "jwttest",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("hello_worldhello_worldhello_worldhello_world")),
        };
    });
    //注册授权服务
    services.AddAuthorization();
    services.AddGrpc();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	//...省略
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGrpcService<GreeterService>();
        //添加授权服务
        endpoints.MapGrpcService<AuthService>();
		//...省略
    });
}

二、客户端获取Token认证


修改 GrpcDemo.Clint > Program.cs > Main

class Program
{
    private const string ServiceAddress = "https://localhost:5001";

    static void Main(string[] args)
    {
        var channel = GetAuthGrpcChannel();
        var task = AuthTest(channel);
        task.Wait();
    }

    /// <summary>
    /// 获取已身份认证的GrpcChannel
    /// </summary>
    public static GrpcChannel GetAuthGrpcChannel()
    {
        var channel = GrpcChannel.ForAddress(ServiceAddress);
        var authClient = new Auth.AuthClient(channel);
        //获取Token
        var token = authClient.GetToken(new AuthData()
        {
            Name = "alice",
            Pass = "alice"
        });
        channel.Dispose();
        //创建Authorization证书
        var credentials = CallCredentials.FromInterceptor((context, metadata) =>
        {
            if (!string.IsNullOrEmpty(token.Token))
            {
                metadata.Add("Authorization", $"Bearer {token.Token}");
            }
            return Task.CompletedTask;
        });
        //创建具有Token的通道
        var auth_channel = GrpcChannel.ForAddress(ServiceAddress, new GrpcChannelOptions()
        {
            Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
        });
        return auth_channel;
    }

    /// <summary>
    /// 测试身份认证
    /// </summary>
    /// <param name="invoker"></param>
    /// <returns></returns>
    public static async Task AuthTest(GrpcChannel channel)
    {
        Console.WriteLine("AuthTest");
        var authClient = new Auth.AuthClient(channel);
        await authClient.TestAsync(new Empty());
        Console.WriteLine("AuthSuccess");
    }
}

GetAuthGrpcChannel获取已认证的RrpcChannel,调用该通道运行AuthTest方法


三、运行并查看结果

输出:
输出


参考资料

微软官方Grpc教程
Grpc英文文档

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.NET Core是微软开源的跨平台框架,可以用于构建Web应用程序、Web API、微服务和其他类型的应用程序。gRPC是一种高性能、开源的远程过程调用(RPC)框架,它使用Protocol Buffers作为序列化协议。 在.NET Core中,可以使用gRPC框架来构建高性能、跨平台的微服务。gRPC框架提供了基于Protocol Buffers的定义和代码生成工具,使得开发人员可以轻松地定义和实现RPC接口。gRPC框架还提供了基于HTTP/2的双向流式传输,这意味着客户端和服务器可以同时发送和接收多个消息,从而提高了系统的吞吐量和性能。 使用gRPC框架开发微服务的步骤如下: 1. 定义gRPC服务:使用Protocol Buffers定义接口和消息类型。 2. 生成代码:使用gRPC工具生成客户端和服务器端代码。 3. 实现服务:实现服务器端接口。 4. 创建客户端:创建gRPC客户端并调用服务。 .NET Core提供了丰富的工具和库来支持gRPC开发,包括: 1. gRPC工具:可以使用gRPC工具从Protocol Buffers文件生成代码。 2. gRPC.AspNetCore:可以使用gRPC.AspNetCore库在ASP.NET Core应用程序中托管gRPC服务。 3. gRPC.Net.Client:可以使用gRPC.Net.Client库创建gRPC客户端。 4. gRPC.Tools:可以使用gRPC.Tools库在Visual Studio中集成gRPC工具。 总之,.NET Core提供了完整的支持gRPC的框架和工具,使得开发人员可以轻松地构建高性能、跨平台的微服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值