1 # Copyright 2019 The gRPC Authors
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """Server of the Python example of customizing authentication mechanism."""
16 from __future__ import absolute_import
17 from __future__ import division
18 from __future__ import print_function
23 from concurrent import futures
26 from examples import helloworld_pb2
27 from examples import helloworld_pb2_grpc
28 from examples.python.auth import _credentials
30 _LOGGER = logging.getLogger(__name__)
31 _LOGGER.setLevel(logging.INFO)
33 _LISTEN_ADDRESS_TEMPLATE = 'localhost:%d'
34 _SIGNATURE_HEADER_KEY = 'x-signature'
37 class SignatureValidationInterceptor(grpc.ServerInterceptor):
41 def abort(ignored_request, context):
42 context.abort(grpc.StatusCode.UNAUTHENTICATED, 'Invalid signature')
44 self._abortion = grpc.unary_unary_rpc_method_handler(abort)
46 def intercept_service(self, continuation, handler_call_details):
47 # Example HandlerCallDetails object:
48 # _HandlerCallDetails(
49 # method=u'/helloworld.Greeter/SayHello',
50 # invocation_metadata=...)
51 method_name = handler_call_details.method.split('/')[-1]
52 expected_metadata = (_SIGNATURE_HEADER_KEY, method_name[::-1])
53 if expected_metadata in handler_call_details.invocation_metadata:
54 return continuation(handler_call_details)
59 class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer):
61 def SayHello(self, request, unused_context):
62 return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
65 @contextlib.contextmanager
67 # Bind interceptor to server
68 server = grpc.server(futures.ThreadPoolExecutor(),
69 interceptors=(SignatureValidationInterceptor(),))
70 helloworld_pb2_grpc.add_GreeterServicer_to_server(SimpleGreeter(), server)
73 server_credentials = grpc.ssl_server_credentials(((
74 _credentials.SERVER_CERTIFICATE_KEY,
75 _credentials.SERVER_CERTIFICATE,
78 # Pass down credentials
79 port = server.add_secure_port(_LISTEN_ADDRESS_TEMPLATE % port,
90 parser = argparse.ArgumentParser()
91 parser.add_argument('--port',
95 help='the listening port')
96 args = parser.parse_args()
98 with run_server(args.port) as (server, port):
99 logging.info('Server is listening at port :%d', port)
100 server.wait_for_termination()
103 if __name__ == '__main__':
104 logging.basicConfig(level=logging.INFO)