grpc / grpc.github.io

The grpc.io website. (on GitHub pages)
276 stars 381 forks source link

Python client authentication example #768

Open maged opened 5 years ago

maged commented 5 years ago

The authentication docs cover server authentication, but not client authentication. Is it possible to add a client authentication example to the docs. Does it require using other flags in grpc.ssl_channel_credentials?

carl-mastrangelo commented 5 years ago

cc: @lidizheng

lidizheng commented 5 years ago

@maged In the doc, it provides example of TLS with Client Authentication which is default for gRPC, meaning both server and client should have certificates.

Or what you want is to perform the normal TLS without Client Authentication?

lidizheng commented 5 years ago

If you would like to enforce the client authentication, you can set the require_client_auth for your ssl_server_credentials. For more details, check the API Reference.

maged commented 5 years ago

The solution I got to (which the API reference for ssl_channel_credentials was more helpful for) is to use these three flags:

    creds = grpc.ssl_channel_credentials(
            certificate_chain=cert_chain, private_key=cert_key, root_certificates=root_ca)

certificate_chain and private_key are the client's cert and private key that the server will verify. root_certificates is the root CA that the server will be verified against.

Might be useful to have this example in the docs as well.

maged commented 5 years ago

Just to confirm, this only verifies that the client's certificate is signed by the root CA given, right? Is their anyway to verify the client CN against an expected CN?

lidizheng commented 5 years ago

@maged

Just to confirm, this only verifies that the client's certificate is signed by the root CA given, right?

Yes. It depends on your server's setting of require_client_auth. If you set it to True then the server will request and require client certificate and verify it, for more details. If you set it to False, the server won't request the certificate at all.

Is their anyway to verify the client CN against an expected CN?

Please check this unit test. The Python server handler will get a servicer_context where contains a servicer_context.auth_context(), you can access the verified expected CN from that. Generally speaking, it is quite hard for server to get precise CN for incoming client. But you can implement your verification logic in your handler.

Does that answer your question?