带入gRPC:对 RPC 方法做自定义认证

原文地址:带入gRPC:对 RPC 方法做自定义认证
项目地址:https://github.com/EDDYCJY/go...

前言

在前面的章节中,我们介绍了两种(证书算一种)可全局认证的方法:

  1. TLS 证书认证
  2. 基于 CA 的 TLS 证书认证
  3. Unary and Stream interceptor

而在实际需求中,常常会对某些模块的 RPC 方法做特殊认证或校验。今天将会讲解、实现这块的功能点

课前知识


type PerRPCCredentials interface {
GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
RequireTransportSecurity() bool
}

在 gRPC 中默认定义了 PerRPCCredentials,它就是本章节的主角,是 gRPC 默认提供用于自定义认证的接口,它的作用是将所需的安全认证信息添加到每个 RPC 方法的上下文中。其包含 2 个方法:

  • GetRequestMetadata:获取当前请求认证所需的元数据(metadata)
  • RequireTransportSecurity:是否需要基于 TLS 认证进行安全传输

目录结构

新建 simple_token_server/server.go 和 simple_token_client/client.go,目录结构如下:


go-grpc-example
├── client
│   ├── simple_client
│   ├── simple_http_client
│   ├── simple_token_client
│   └── stream_client
├── conf
├── pkg
├── proto
├── server
│   ├── simple_http_server
│   ├── simple_server
│   ├── simple_token_server
│   └── stream_server
└── vendor

gRPC

Client


package main import (
"context"
"log" "google.golang.org/grpc" "github.com/EDDYCJY/go-grpc-example/pkg/gtls"
pb "github.com/EDDYCJY/go-grpc-example/proto"
) const PORT = "9004" type Auth struct {
AppKey string
AppSecret string
} func (a *Auth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{"app_key": a.AppKey, "app_secret": a.AppSecret}, nil
} func (a *Auth) RequireTransportSecurity() bool {
return true
} func main() {
tlsClient := gtls.Client{
ServerName: "go-grpc-example",
CertFile: "../../conf/server/server.pem",
}
c, err := tlsClient.GetTLSCredentials()
if err != nil {
log.Fatalf("tlsClient.GetTLSCredentials err: %v", err)
} auth := Auth{
AppKey: "eddycjy",
AppSecret: "20181005",
}
conn, err := grpc.Dial(":"+PORT, grpc.WithTransportCredentials(c), grpc.WithPerRPCCredentials(&auth))
...
}

在 Client 端,重点实现 type PerRPCCredentials interface 所需的方法,关注两点即可:

  • struct Auth:GetRequestMetadata、RequireTransportSecurity
  • grpc.WithPerRPCCredentials

Server


package main import (
"context"
"log"
"net" "google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status" "github.com/EDDYCJY/go-grpc-example/pkg/gtls"
pb "github.com/EDDYCJY/go-grpc-example/proto"
) type SearchService struct {
auth *Auth
} func (s *SearchService) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
if err := s.auth.Check(ctx); err != nil {
return nil, err
}
return &pb.SearchResponse{Response: r.GetRequest() + " Token Server"}, nil
} const PORT = "9004" func main() {
...
} type Auth struct {
appKey string
appSecret string
} func (a *Auth) Check(ctx context.Context) error {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return status.Errorf(codes.Unauthenticated, "自定义认证 Token 失败")
} var (
appKey string
appSecret string
)
if value, ok := md["app_key"]; ok {
appKey = value[0]
}
if value, ok := md["app_secret"]; ok {
appSecret = value[0]
} if appKey != a.GetAppKey() || appSecret != a.GetAppSecret() {
return status.Errorf(codes.Unauthenticated, "自定义认证 Token 无效")
} return nil
} func (a *Auth) GetAppKey() string {
return "eddycjy"
} func (a *Auth) GetAppSecret() string {
return "20181005"
}

在 Server 端就更简单了,实际就是调用 metadata.FromIncomingContext 从上下文中获取 metadata,再在不同的 RPC 方法中进行认证检查

验证

重新启动 server.go 和 client.go,得到以下结果:


$ go run client.go
2018/10/05 20:59:58 resp: gRPC Token Server

修改 client.go 的值,制造两者不一致,得到无效结果:


$ go run client.go
2018/10/05 21:00:05 client.Search err: rpc error: code = Unauthenticated desc = invalid token
exit status 1

一个个加太麻烦

我相信你肯定会问一个个加,也太麻烦了吧?有这个想法的你,应当把 type PerRPCCredentials interface 做成一个拦截器(interceptor)

总结

本章节比较简单,主要是针对 RPC 方法的自定义认证进行了介绍,如果是想做全局的,建议是举一反三从拦截器下手哦

带入gRPC:对 RPC 方法做自定义认证的更多相关文章

  1. DRF认证、自定义认证和权限、自定义权限

    源码分析 """ 1)APIView的dispath(self, request, *args, **kwargs) 2)dispath方法内 self.initial( ...

  2. drf三大认证:认证组件-权限组件-权限六表-自定义认证组件的使用

    三大认证工作原理简介 认证.权限.频率 源码分析: from rest_framework.views import APIView 源码分析入口: 内部的三大认证方法封装: 三大组件的原理分析: 权 ...

  3. 跟我一起学Go系列:Go gRPC 安全认证方式-Token和自定义认证

    Go gRPC 系列: 跟我一起学Go系列:gRPC安全认证机制-SSL/TLS认证 跟我一起学 Go 系列:gRPC 拦截器使用 跟我一起学 Go 系列:gRPC 入门必备 接上一篇继续讲 gRPC ...

  4. gRPC【RPC自定义http2.0协议传输】

    gRPC 简介 gRPC是由Google公司开源的高性能RPC框架. gRPC支持多语言 gRPC原生使用C.Java.Go进行了三种实现,而C语言实现的版本进行封装后又支持C++.C#.Node.O ...

  5. asp.net core 自定义认证方式--请求头认证

    asp.net core 自定义认证方式--请求头认证 Intro 最近开始真正的实践了一些网关的东西,最近写几篇文章分享一下我的实践以及遇到的问题. 本文主要介绍网关后面的服务如何进行认证. 解决思 ...

  6. go微服务框架go-micro深度学习(四) rpc方法调用过程详解

    上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取server的地 ...

  7. go微服务框架go-micro深度学习 rpc方法调用过程详解

    摘要: 上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取serv ...

  8. Spring集成shiro做登陆认证

    一.背景 其实很早的时候,就在项目中有使用到shiro做登陆认证,直到今天才又想起来这茬,自己抽空搭了一个spring+springmvc+mybatis和shiro进行集成的种子项目,当然里面还有很 ...

  9. 【Spring Security】六、自定义认证处理的过滤器

    这里接着上一章的自定义过滤器,这里主要的是配置自定义认证处理的过滤器,并加入到FilterChain的过程.在我们自己不在xml做特殊的配置情况下,security默认的做认证处理的过滤器为Usern ...

随机推荐

  1. sklearn学习5-----模型评估(1) 分类度量

    一.分类度量 1.混淆矩阵: 2.classification_report 3.汉明损失 4.jaccard相似系数得分 5.准确率.召回率和F_measure 3.

  2. 51nod 1576 Tree and permutation(树的重心+dfn序)

    乍一看我不会. 先不考虑加点. 先考虑没有那个除\(2\). 考虑每一条边的贡献,假设某一条边把这棵树分成大小为x,y的两个部分. 那么这条边最多可以被使用\(min(x,y)*2\)次(因为有进有出 ...

  3. 【NOI2001】食物链

    [NOI2001]食物链 题意 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B ...

  4. HDU 6149 Valley Numer II (状压DP 易错题)

    题目大意:给你一个无向连通图(n<=30),点分为高点和低点,高点数量<=15,如果两个高点和低点都直接连边,那么我们称这三个点形成一个valley,每个点最多作为一个valley的组成部 ...

  5. CF1037E Trips (离线+图上构造)

    题目大意:一共有n个人,每天早上会有两个人成为朋友,朋友关系不具有传递性,晚上,它们会组织旅游,如果一个人去旅游,那么他不少于$k$个朋友也要和他去旅游,求每天的最大旅游人数 一开始并没有想到反向建图 ...

  6. thinkphp 多个字段的不同关系的查询条件实现 .

    tp的$map不同条件默认是 and ,如果要用or<><><><>如下 例如查询Stu表中年龄大于18,或者身高低于180cm的男性(1为男性),(例 ...

  7. 查看系统的I/O使用iostat命令而使用iotop能够依据I/O统计信息排序,追踪到详细的进程

    当看到I/O等待时间所占CPU时间的比重非常高的时候,首先要检查的就是机器是否正在大量使用交换空间,由于硬盘操作的速度远远低于RAM.所以当系统内存耗尽,開始使用交换空间的时候.系统的性能会受到严重影 ...

  8. 《Objective-C高级编程:iOS与OS X多线程和内存管理》读后感

    拿到这本书的第一感觉是非常薄,可是内容就如同序里面所说,这不是一本面向刚開始学习的人的书,比較有深度,对C/C++全然不熟悉的话非常多东西会看不明确. 尽管此书在技术点上仅仅谈到了ARC.Blocks ...

  9. 【Android】桌面歌词悬浮效果简单实现

    在使用"网易云音乐"的时候,发现有一个显示"桌面歌词"的功能,于是就想着自己实现下.查了下资料,是用WindowManage实现的.实现过程中也出现了些问题,看 ...

  10. EF的CRUD

    已经知道EF就是一个能够使得编程人员用面向对象的思想操作数据库的框架,那么在最初学习SQL的时候我们就知道对数据库的操作就是增删改查.万变不离其宗. EF也是操作数据库的当然也就是要对数据库实现增删改 ...