Golang GRPC Practice serial Four GRPC certification

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

The GRPC provides two authentication methods by default:

    • Based on SSL/TLS authentication method

    • Remote Call authentication method

Two ways to mix it up

TLS Authentication Example

This directly expands the Hello project to implement the TLS authentication mechanism

First you need to prepare a certificate, in the Hello directory the new keys directory is used to store the certificate file.

Certificate making

Making the private key (. Key)

# Key considerations for algorithm "RSA" ≥ 2048-bitopenssl genrsa -out server.key 2048    # Key considerations for algorithm "ECDSA" ≥ secp384r1# List ECDSA the supported curves (openssl ecparam -list_curves)openssl ecparam -genkey -name secp384r1 -out server.key

Self-signed public key (X509) (pem-encodings .pem | .crt )

openssl req -new -x509 -sha256 -key server.key -out server.pem -days 3650

Custom Information

-----Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:XxXxLocality Name (eg, city) []:XxXxOrganization Name (eg, company) [Internet Widgits Pty Ltd]:XX Co. LtdOrganizational Unit Name (eg, section) []:DevCommon Name (e.g. server FQDN or YOUR name) []:server nameEmail Address []:xxx@xxx.com

Directory structure

$GOPATH/src/grpc-go-practice/example/|—— hello-tls/    |—— client/        |—— main.go   // 客户端    |—— server/        |—— main.go   // 服务端|—— keys/                 // 证书目录    |—— server.key    |—— server.pem|—— proto/    |—— hello.proto   // proto描述文件    |—— hello.pb.go   // proto编译后文件

Sample code

proto/helloworld.protoand proto/hello.pb.go documents need not be changed

Modify server-side code: SERVER/MAIN.GO

Package Mainimport ("net" PB "Go-grpc-practice/example/proto" "Golang.org/x/net/context" "google.golang.org/g RPC "Google.golang.org/grpc/credentials"//Introduction of GRPC Certification Package "Google.golang.org/grpc/grpclog") const (//Address GRPC Service  Address = "127.0.0.1:50052")//define HelloService and implement the agreed interface type HelloService struct{}//helloservice ... var helloservice = Helloservice{}func (H helloservice) SayHello (CTX context. Context, in *PB. Hellorequest) (*PB. Helloreply, error) {resp: = new (Pb). helloreply) resp. Message = "Hello" + in.    Name + "." Return resp, Nil}func main () {listen, err: = Net. Listen ("TCP", Address) if err! = Nil {grpclog. Fatalf ("Failed to listen:%v", err)}//TLS authentication creds, ERR: = credentials. Newservertlsfromfile (".. /.. /keys/server.pem ",". /.. /keys/server.key ") if err! = Nil {grpclog. Fatalf ("Failed to generate credentials%v", err)}//Instantiate Grpc Server and turn on TLS authentication s: = Grpc. NewServer (GRPC. Creds (creds))//Register HelloService    Pb. Registerhelloserver (S, HelloService) Grpclog. Println ("Listen on" + Address + "with TLS") S.serve (Listen)}

Run:

go run main.goListen on 127.0.0.1:50052 with TLS

The service side can configure multiple options when instantiating GRPC server, one of which is TLS authentication

Client Add TLS authentication: Client/main.go

package mainimport (    pb "go-grpc-practice/example/proto" // 引入proto包    "golang.org/x/net/context"    "google.golang.org/grpc"    "google.golang.org/grpc/credentials" // 引入grpc认证包    "google.golang.org/grpc/grpclog")const (    // Address gRPC服务地址    Address = "127.0.0.1:50052")func main() {    // TLS连接    creds, err := credentials.NewClientTLSFromFile("../../keys/server.pem", "server name")    if err != nil {        grpclog.Fatalf("Failed to create TLS credentials %v", err)    }    conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(creds))    if err != nil {        grpclog.Fatalln(err)    }    defer conn.Close()    // 初始化客户端    c := pb.NewHelloClient(conn)    // 调用方法    reqBody := new(pb.HelloRequest)    reqBody.Name = "gRPC"    r, err := c.SayHello(context.Background(), reqBody)    if err != nil {        grpclog.Fatalln(err)    }    grpclog.Println(r.Message)}

Run:

go run main.goHello gRPC

The client adds TLS authentication in a similar manner to the server, where you Dial can configure multiple options when creating a connection, and more options are shown in the following example.

Token Authentication Example

Further, continue to expand the HELLO-TLS project to implement the TLS + token authentication mechanism

Directory structure

$GOPATH/src/grpc-go-practice/example/|—— hello-token/    |—— client/        |—— main.go   // 客户端    |—— server/        |—— main.go   // 服务端|—— keys/             // 证书目录    |—— server.key    |—— server.pem|—— proto/    |—— hello.proto   // proto描述文件    |—— hello.pb.go   // proto编译后文件

Sample code

Client implementation: Client/main.go

Package Mainimport (pb "Go-grpc-practice/example/proto"//introduced Proto Pack "Golang.org/x/net/context" "google.golang.or G/grpc "Google.golang.org/grpc/credentials"//Introduction of GRPC Authentication package "Google.golang.org/grpc/grpclog") const (//Address GRP C Service address = "127.0.0.1:50052"//Opentls whether to turn on TLS authentication OPENTLS = true)//customcredential Custom Authentication type Customcredent Ial Struct{}func (c customcredential) Getrequestmetadata (CTX context. Context, Uri, String) (map[string]string, error) {return map[string]string{"AppID": "101010", "Appke    Y ":" I am Key ",}, Nil}func (c customcredential) requiretransportsecurity () bool {if OPENTLS {return true } return False}func Main () {var err error var opts []GRPC. Dialoption if OPENTLS {//TLS connection creds, err: = credentials. Newclienttlsfromfile (".. /.. /keys/server.pem "," server name ") If err! = Nil {grpclog. Fatalf ("Failed to create TLS credentials%v", err)} opts= Append (opts, Grpc. Withtransportcredentials (creds))} else {opts = append (opts, Grpc. Withinsecure ())}//Use custom Authentication opts = Append (opts, Grpc. Withperrpccredentials (New (customcredential))) conn, err: = Grpc.    Dial (Address, opts ...) If err! = Nil {grpclog. Fatalln (ERR)} defer conn. Close ()//Initialize client c: = PB. Newhelloclient (conn)//Call method Reqbody: = new (Pb). hellorequest) Reqbody.name = "Grpc" r, Err: = C.sayhello (context. Background (), reqbody) if err! = Nil {grpclog. Fatalln (Err)} grpclog. Println (R.message)}

Here we define a customCredential structure and implement two methods GetRequestMetadata and RequireTransportSecurity . This is the custom authentication method provided by GRPC, and each RPC call transmits authentication information. customCredentialis actually implementing the grpc/credential interface within the package PerRPCCredentials . Each invocation, token information is transmitted to the server via the requested metadata. The following is a detailed look at how the server gets the information in metadata.

To modify the SayHello method in Server/main.go:

Package Mainimport ("FMT" "Net" PB "Go-grpc-practice/example/proto" "Golang.org/x/net/context" "Google.gol Ang.org/grpc "" Google.golang.org/grpc/codes "" google.golang.org/grpc/credentials "//introduced GRPC certification package" google.golang.org /grpc/grpclog "Google.golang.org/grpc/metadata"//introduction of GRPC meta-package) const (//Address GRPC Service addresses = "127.0.0.1 : 50052 ")//define HelloService and implement the agreed interface type HelloService struct{}//helloservice ... var helloservice = Helloservice{}func (h HelloService) SayHello (CTX context. Context, in *PB. Hellorequest) (*PB. Helloreply, error) {//parse the information in Metada and verify MD, OK: = metadata. Fromcontext (CTX) if!ok {return nil, grpc. Errorf (codes. Unauthenticated, "No token authentication information")} var (AppID string Appkey string) if val, ok: = md["AppID"]; OK {AppID = val[0]} If val, ok: = md["Appkey"]; OK {appkey = val[0]} if AppID! = "101010" | | Appkey! = "I am key" {return nil, grpc. Errorf (codes. Unauthenticated, "Token Authentication information Invalid: appid=%s, appkey=%s", AppID, Appkey)} RESP: = new (Pb). helloreply) resp. Message = FMT. Sprintf ("Hello%s.\ntoken info:appid=%s,appkey=%s", in. Name, AppID, Appkey) return resp, Nil}func main () {listen, err: = Net. Listen ("TCP", Address) if err! = Nil {grpclog. Fatalf ("Failed to listen:%v", err)}//TLS authentication creds, ERR: = credentials. Newservertlsfromfile (".. /.. /keys/server.pem ",". /.. /keys/server.key ") if err! = Nil {grpclog. Fatalf ("Failed to generate credentials%v", err)}//Instantiate Grpc Server and turn on TLS authentication s: = Grpc. NewServer (GRPC. Creds (creds))//Registered HelloService PB. Registerhelloserver (S, HelloService) Grpclog. Println ("Listen on" + Address + "with TLS + Token") S.serve (Listen)}

Run:

go run main.goListen on 50052 with TLS + Token

Run the client program Client/main.go:

go run main.go// 认证成功结果Hello gRPCToken info: appid=101010,appkey=i am key// 认证失败结果:rpc error: code = 16 desc = Token认证信息无效: appID=101010, appKey=i am not key

Reference

Sample code for this series

    • Go-grpc-example

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.