For most common usage of authentication in gRPC Python, please see our Authentication guide's Python section. The Guide includes following scenarios:
- Server SSL credential setup
- Client SSL credential setup
- Authenticate with Google using a JWT
- Authenticate with Google using an Oauth2 token
Also, the guide talks about gRPC specific credential types.
Channel credentials are attached to a Channel
object, the most common use case
are SSL credentials.
Call credentials are attached to a Call
object (corresponding to an RPC).
Under the hood, the call credentials is a function that takes in information of
the RPC and modify metadata through callback.
This example focuses on extending gRPC authentication mechanism:
- Customize authentication plugin;
- Composite client side credentials;
- Validation through interceptor on server side.
Unlike TLS/SSL based authentication, the authentication extension in gRPC Python lives at a much higher level of networking. It relies on the transmission of metadata (HTTP Header) between client and server, instead of alternating the transport protocol.
gRPC Python provides a way to intercept an RPC and append authentication related
metadata through
AuthMetadataPlugin
.
Those in need of a custom authentication method may simply provide a concrete
implementation of the following interface:
class AuthMetadataPlugin:
"""A specification for custom authentication."""
def __call__(self, context, callback):
"""Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
Args:
context: An AuthMetadataContext providing information on the RPC that
the plugin is being called to authenticate.
callback: An AuthMetadataPluginCallback to be invoked either
synchronously or asynchronously.
"""
Then pass the instance of the concrete implementation to
grpc.metadata_call_credentials
function to be converted into a
CallCredentials
object. Please NOTE that it is possible to pass a Python
function object directly, but we recommend to inherit from the base class to
ensure implementation correctness.
def metadata_call_credentials(metadata_plugin, name=None):
"""Construct CallCredentials from an AuthMetadataPlugin.
Args:
metadata_plugin: An AuthMetadataPlugin to use for authentication.
name: An optional name for the plugin.
Returns:
A CallCredentials.
"""
The CallCredentials
object can be passed directly into an RPC like:
call_credentials = grpc.metadata_call_credentials(my_foo_plugin)
stub.FooRpc(request, credentials=call_credentials)
Or you can use ChannelCredentials
and CallCredentials
at the same time by
combining them:
channel_credentials = ...
call_credentials = ...
composite_credentials = grpc.composite_channel_credentials(
channel_credential,
call_credentials)
channel = grpc.secure_channel(server_address, composite_credentials)
It is also possible to apply multiple CallCredentials
to a single RPC:
call_credentials_foo = ...
call_credentials_bar = ...
call_credentials = grpc.composite_call_credentials(
call_credentials_foo,
call_credentials_bar)
stub.FooRpc(request, credentials=call_credentials)
Instead of AuthMetadataPlugin
, you can also use token-based authentication
mechanisms using OAuth2 tokens or other customized tokens.
OAuth2 tokens can be obtained using libraries like google-auth:
import google.auth
google_credentials, unused_project_id = google.auth.default()
call_credentials = grpc.access_token_call_credentials(google_credentials.token)
After obtaining the token, the rest of the flow is documented in token_based_auth_client.py and token_based_auth_server.py.