gRPC 认证的例子
认证机制提供大部分编程语言的API。下面展示上一节关于认证和授权功能在主流编程语言中的例子。
Go语言
没有加密或验证
客户端:
conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure()) // error handling omitted client := pb.NewGreeterClient(conn) // ...
服务器端:
s := grpc.NewServer() lis, _ := net.Listen("tcp", "localhost:50051") // error handling omitted s.Serve(lis)
使用服务器身份验证SSL/TLS
客户端:
creds, _ := credentials.NewClientTLSFromFile(certFile, "") conn, _ := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(creds)) // error handling omitted client := pb.NewGreeterClient(conn) // ...
服务器端:
creds, _ := credentials.NewServerTLSFromFile(certFile, keyFile) s := grpc.NewServer(grpc.Creds(creds)) lis, _ := net.Listen("tcp", "localhost:50051") // error handling omitted s.Serve(lis)
使用谷歌认证
pool, _ := x509.SystemCertPool() // error handling omitted creds := credentials.NewClientTLSFromCert(pool, "") perRPC, _ := oauth.NewServiceAccountFromFile("service-account.json", scope) conn, _ := grpc.Dial( "greeter.googleapis.com", grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(perRPC), ) // error handling omitted client := pb.NewGreeterClient(conn) // ...
Ruby
没有加密或验证
stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure) ...
使用服务器身份验证SSL/TLS
creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)
使用谷歌认证
require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0 ... ssl_creds = GRPC::Core::ChannelCredentials.new(load_certs) # load_certs typically loads a CA roots file authentication = Google::Auth.get_application_default() call_creds = GRPC::Core::CallCredentials.new(authentication.updater_proc) combined_creds = ssl_creds.compose(call_creds) stub = Helloworld::Greeter::Stub.new('greeter.googleapis.com', combined_creds)
C++
没有加密或验证
auto channel = grpc::CreateChannel("localhost:50051", InsecureChannelCredentials()); std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel)); ...
使用服务器身份验证SSL/TLS
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); auto channel = grpc::CreateChannel("myservice.example.com", channel_creds); std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel)); ...
使用谷歌认证
auto creds = grpc::GoogleDefaultCredentials(); auto channel = grpc::CreateChannel("greeter.googleapis.com", creds); std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel)); ...
C#
没有加密或验证
var channel = new Channel("localhost:50051", ChannelCredentials.Insecure); var client = new Greeter.GreeterClient(channel); ...
使用服务器身份验证SSL/TLS
var channelCredentials = new SslCredentials(File.ReadAllText("roots.pem")); // Load a custom roots file. var channel = new Channel("myservice.example.com", channelCredentials); var client = new Greeter.GreeterClient(channel);
使用谷歌认证
using Grpc.Auth; // from Grpc.Auth NuGet package ... // Loads Google Application Default Credentials with publicly trusted roots. var channelCredentials = await GoogleGrpcCredentials.GetApplicationDefaultAsync(); var channel = new Channel("greeter.googleapis.com", channelCredentials); var client = new Greeter.GreeterClient(channel); ...
验证单个RPC调用
var channel = new Channel("greeter.googleapis.com", new SslCredentials()); // Use publicly trusted roots. var client = new Greeter.GreeterClient(channel); ... var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); var result = client.SayHello(request, new CallOptions(credentials: googleCredential.ToCallCredentials())); ...
Python
没有加密或验证
import grpc import helloworld_pb2 channel = grpc.insecure_channel('localhost:50051') stub = helloworld_pb2.GreeterStub(channel)
使用服务器身份验证SSL/TLS
客户端:
import grpc import helloworld_pb2 with open('roots.pem', 'rb') as f: creds = grpc.ssl_channel_credentials(f.read()) channel = grpc.secure_channel('myservice.example.com:443', creds) stub = helloworld_pb2.GreeterStub(channel)
服务器端:
import grpc import helloworld_pb2 from concurrent import futures server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) with open('key.pem', 'rb') as f: private_key = f.read() with open('chain.pem', 'rb') as f: certificate_chain = f.read() server_credentials = grpc.ssl_server_credentials( ( (private_key, certificate_chain), ) ) # Adding GreeterServicer to server omitted server.add_secure_port('myservice.example.com:443', server_credentials) server.start() # Server sleep omitted
使用JWT进行谷歌认证
import grpc import helloworld_pb2 from google import auth as google_auth from google.auth import jwt as google_auth_jwt from google.auth.transport import grpc as google_auth_transport_grpc credentials, _ = google_auth.default() jwt_creds = google_auth_jwt.OnDemandCredentials.from_signing_credentials( credentials) channel = google_auth_transport_grpc.secure_authorized_channel( jwt_creds, None, 'greeter.googleapis.com:443') stub = helloworld_pb2.GreeterStub(channel)
使用谷歌认证 using an Oauth2 token
import grpc import helloworld_pb2 from google import auth as google_auth from google.auth.transport import grpc as google_auth_transport_grpc from google.auth.transport import requests as google_auth_transport_requests credentials, _ = google_auth.default(scopes=(scope,)) request = google_auth_transport_requests.Request() channel = google_auth_transport_grpc.secure_authorized_channel( credentials, request, 'greeter.googleapis.com:443') stub = helloworld_pb2.GreeterStub(channel)
Java
没有加密或验证
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051) .usePlaintext(true) .build(); GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
使用服务器身份验证SSL/TLS
在Java中,我们建议您在TLS上使用gRPC时启用OpenSSL。你可以在gRPC Java安全文档中找到关于安装和使用OpenSSL和其他Android和非Android Java所需库的详细信息。
要在服务器上启用TLS,需要以PEM格式指定证书链和私钥。这种私钥不应该使用密码。链中证书的顺序很重要:更具体地说,顶部的证书必须是主机CA,而最底部的证书必须是根CA。标准TLS端口是443,但是我们使用8443端口来避免跟OS冲突。
Server server = ServerBuilder.forPort(8443)
// Enable TLS
.useTransportSecurity(certChainFile, privateKeyFile)
.addService(TestServiceGrpc.bindService(serviceImplementation))
.build();
server.start();
如果客户端不知道发行证书颁发机构,则应向NettyChannelBuilder或OkHttpChannelBuilder分别提供正确配置的SslContext或SSLSocketFactory。
在客户端,使用SSL/TLS的服务器身份验证如下所示:
// 使用服务器身份验证SSL/TLS ManagedChannel channel = ManagedChannelBuilder.forAddress("myservice.example.com", 443) .build(); GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel); // 使用服务器身份验证SSL/TLS; custom CA root certificates; not on Android ManagedChannel channel = NettyChannelBuilder.forAddress("myservice.example.com", 443) .sslContext(GrpcSslContexts.forClient().trustManager(new File("roots.pem")).build()) .build(); GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel);
使用谷歌认证
下面的代码片段展示了如何使用带有服务帐户的gRPC调用Google Cloud PubSub API。证书是从存储在众所周知的位置的密钥加载的,或者通过检测到应用程序正在能够自动提供证书的环境中运行,例如谷歌计算引擎。虽然这个例子是针对谷歌及其服务的,但是其他服务提供商也可以遵循类似的模式。
GoogleCredentials creds = GoogleCredentials.getApplicationDefault(); ManagedChannel channel = ManagedChannelBuilder.forTarget("greeter.googleapis.com") .build(); GreeterGrpc.GreeterStub stub = GreeterGrpc.newStub(channel) .withCallCredentials(MoreCallCredentials.from(creds)); Node.js Base case - No encryption/authentication var stub = new helloworld.Greeter('localhost:50051', grpc.credentials.createInsecure());
使用服务器身份验证SSL/TLS
var ssl_creds = grpc.credentials.createSsl(root_certs); var stub = new helloworld.Greeter('myservice.example.com', ssl_creds);
使用谷歌认证
// Authenticating with Google var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library ... var ssl_creds = grpc.credentials.createSsl(root_certs); (new GoogleAuth()).getApplicationDefault(function(err, auth) { var call_creds = grpc.credentials.createFromGoogleCredential(auth); var combined_creds = grpc.credentials.combineChannelCredentials(ssl_creds, call_creds); var stub = new helloworld.Greeter('greeter.googleapis.com', combined_credentials); });
使用Oauth2 token进行谷歌认证
var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library ... var ssl_creds = grpc.Credentials.createSsl(root_certs); // load_certs typically loads a CA roots file var scope = 'https://www.googleapis.com/auth/grpc-testing'; (new GoogleAuth()).getApplicationDefault(function(err, auth) { if (auth.createScopeRequired()) { auth = auth.createScoped(scope); } var call_creds = grpc.credentials.createFromGoogleCredential(auth); var combined_creds = grpc.credentials.combineChannelCredentials(ssl_creds, call_creds); var stub = new helloworld.Greeter('greeter.googleapis.com', combined_credentials); });
PHP
没有加密或验证
$client = new helloworld\GreeterClient('localhost:50051', [ 'credentials' => Grpc\ChannelCredentials::createInsecure(), ]); ...
使用谷歌认证
function updateAuthMetadataCallback($context) { $auth_credentials = ApplicationDefaultCredentials::getCredentials(); return $auth_credentials->updateMetadata($metadata = [], $context->service_url); } $channel_credentials = Grpc\ChannelCredentials::createComposite( Grpc\ChannelCredentials::createSsl(file_get_contents('roots.pem')), Grpc\CallCredentials::createFromPlugin('updateAuthMetadataCallback') ); $opts = [ 'credentials' => $channel_credentials ]; $client = new helloworld\GreeterClient('greeter.googleapis.com', $opts);
使用Oauth2 token进行谷歌认证
// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set $scope = "https://www.googleapis.com/auth/grpc-testing"; $auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope); $opts = [ 'credentials' => Grpc\Credentials::createSsl(file_get_contents('roots.pem')); 'update_metadata' => $auth->getUpdateMetadataFunc(), ]; $client = new helloworld\GreeterClient('greeter.googleapis.com', $opts);
Dart
没有加密或验证
final channel = new ClientChannel('localhost', port: 50051, options: const ChannelOptions( credentials: const ChannelCredentials.insecure())); final stub = new GreeterClient(channel);
使用服务器身份验证SSL/TLS
// Load a custom roots file. final trustedRoot = new File('roots.pem').readAsBytesSync(); final channelCredentials = new ChannelCredentials.secure(certificates: trustedRoot); final channelOptions = new ChannelOptions(credentials: channelCredentials); final channel = new ClientChannel('myservice.example.com', options: channelOptions); final client = new GreeterClient(channel);
使用谷歌认证
// Uses publicly trusted roots by default. final channel = new ClientChannel('greeter.googleapis.com'); final serviceAccountJson = new File('service-account.json').readAsStringSync(); final credentials = new JwtServiceAccountAuthenticator(serviceAccountJson); final client = new GreeterClient(channel, options: credentials.toCallOptions);
验证单个RPC调用
// Uses publicly trusted roots by default. final channel = new ClientChannel('greeter.googleapis.com'); final client = new GreeterClient(channel); ... final serviceAccountJson = new File('service-account.json').readAsStringSync(); final credentials = new JwtServiceAccountAuthenticator(serviceAccountJson); final response = await client.sayHello(request, options: credentials.toCallOptions);