Python custom authentication

147 views
Skip to first unread message

adul...@gmail.com

unread,
May 22, 2019, 9:25:13 PM5/22/19
to grpc.io

What is the right way of passing the call credentials when using an insecure channel?

I have this client code:

channel = grpc.insecure_channel('localhost:50051')
stub = snippets_pb2_grpc.SnippetsStub(channel)
request = snippets_pb2.SnippetsRequest()
code_snippets = stub.GetAllSnippets(
    request,
    credentials=access_token_call_credentials('my_token')
)

With this, I can't access  provided credentials on the server side. Tried both: context.auth_content() (returns empty dict) and context.invocation_metadata() (doesn't have any token keys).

With the same result I've also tried to extend the grpc.AuthMetadataPlugin class and work this way:

class UsernamePasswordCallCredentials(grpc.AuthMetadataPlugin):
    """Metadata wrapper for raw access token credentials."""

    def __init__(self, username, password):
        self._username = username
        self._password = password

    def __call__(self, context, callback):
        basic_auth = "Basic %s" % base64.b64encode("%s:%s" % (self._username, self._password))
        metadata = (('authorization', basic_auth),)
        callback(metadata, None)

call_creds = metadata_call_credentials(UsernamePasswordCallCredentials('my_name', 'my_password'))


channel = grpc.insecure_channel('localhost:50051')
stub = snippets_pb2_grpc.SnippetsStub(channel)
request = snippets_pb2.SnippetsRequest()
code_snippets = stub.GetAllSnippets(
    request,
    credentials=call_creds
)

Colin Versteeg

unread,
May 23, 2019, 12:24:37 PM5/23/19
to adul...@gmail.com, grpc.io
My understanding is that GRPC is opinionated in this space - because the channel is insecure, it doesn't allow credentials to be sent, to limit MITM. 

I don't recall if it doesn't populate it on the request side, or just doesn't allow you to access it on the Server side. You can check which one by using Wireshark to inspect the communication to determine which.

If you're trying to test locally and will eventually deploy with SSL, can use a self signed certificate with ssl_channel_credentials to test this, passing the cert as the root. 
Another option, if you really want to send credentials in plain-text, would be to just add the token as a random metadata field (stub.getAllSnippets(req, metadata=[("Authorization", "Token")]), and add an interceptor in your server which expects invocation_metadata.



From: grp...@googlegroups.com <grp...@googlegroups.com> on behalf of adul...@gmail.com <adul...@gmail.com>
Sent: Wednesday, May 22, 2019 6:25 PM
To: grpc.io
Subject: [grpc-io] Python custom authentication
 
--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/83c57d08-50e3-4333-a53d-36921da2add1%40googlegroups.com.

adul...@gmail.com

unread,
May 23, 2019, 6:02:25 PM5/23/19
to grpc.io
Thank you for the response!

And yes, later I also tried to create a secure channel with SSL certs used. In that case, I was able to pass creds from the client and read them on the server. Can't say that I understand the motivation for such behavior...
To unsubscribe from this group and stop receiving emails from it, send an email to grp...@googlegroups.com.

Lidi Zheng

unread,
Jun 4, 2019, 2:23:54 PM6/4/19
to grpc.io
Sorry for the confusion. I create a PR to add documentation https://github.com/grpc/grpc/pull/19234.

About the motivation, this behavior is enforced by gRPC C-Core. Core team decided to raise the security bar. Under insecure Channel, attackers can simply sniff your packets and steal your credentials, or simply re-play them.
So, they think it would be better to prevent them in the first place.
Reply all
Reply to author
Forward
0 new messages