From b8c756ecdd7cced1db4300935484e8c83701c82e Mon Sep 17 00:00:00 2001 From: WuKong Date: Tue, 30 Jun 2015 18:47:29 +0200 Subject: migrate moon code from github to opnfv Change-Id: Ice53e368fd1114d56a75271aa9f2e598e3eba604 Signed-off-by: WuKong --- keystone-moon/doc/source/external-auth.rst | 155 +++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 keystone-moon/doc/source/external-auth.rst (limited to 'keystone-moon/doc/source/external-auth.rst') diff --git a/keystone-moon/doc/source/external-auth.rst b/keystone-moon/doc/source/external-auth.rst new file mode 100644 index 00000000..5f3c9af8 --- /dev/null +++ b/keystone-moon/doc/source/external-auth.rst @@ -0,0 +1,155 @@ +=========================================== +Using external authentication with Keystone +=========================================== +.. _external-auth: + +When Keystone is executed in a web server like :doc:`Apache HTTPD +` it is possible to use external authentication methods different +from the authentication provided by the identity store backend or the different +authentication plugins. For example, this makes possible to use an SQL identity +backend together with, X.509 authentication or Kerberos, for example, instead +of using the username and password combination. + +When a web server is in charge of authentication, it is normally possible to +set the ``REMOTE_USER`` environment variable so that it can be used in the +underlying application. Keystone can be configured to use that environment +variable if set, so that the authentication is handled by the web server. + +Configuration +============= + +In Identity API v2, there is no way to disable external authentication. In +order to activate the external authentication mechanism for Identity API v3, +the ``external`` method must be in the list of enabled authentication methods. +By default it is enabled, so if you don't want to use external authentication, +remove it from the ``methods`` option in the ``auth`` section. + +To configure the plugin that should be used set the ``external`` option again +in the ``auth`` section. There are two external authentication method plugins +provided by Keystone: + +* ``keystone.auth.plugins.external.Default``: This plugin won't take into + account the domain information that the external authentication method may + pass down to Keystone and will always use the configured default domain. The + ``REMOTE_USER`` variable is the username. + +* ``keystone.auth.plugins.external.Domain``: This plugin expects that the + ``REMOTE_DOMAIN`` variable contains the domain for the user. If this variable + is not present, the configured default domain will be used. The + ``REMOTE_USER`` variable is the username. + +Using HTTPD authentication +========================== + +Web servers like Apache HTTP support many methods of authentication. Keystone +can profit from this feature and let the authentication be done in the web +server, that will pass down the authenticated user to Keystone using the +``REMOTE_USER`` environment variable. This user must exist in advance in the +identity backend to get a token from the controller. + +To use this method, Keystone should be running on :doc:`HTTPD `. + +X.509 example +------------- + +The following snippet for the Apache conf will authenticate the user based on +a valid X.509 certificate from a known CA:: + + + SSLEngine on + SSLCertificateFile /etc/ssl/certs/ssl.cert + SSLCertificateKeyFile /etc/ssl/private/ssl.key + + SSLCACertificatePath /etc/ssl/allowed_cas + SSLCARevocationPath /etc/ssl/allowed_cas + SSLUserName SSL_CLIENT_S_DN_CN + SSLVerifyClient require + SSLVerifyDepth 10 + + (...) + + +Developing a WSGI middleware for authentication +=============================================== + +In addition to the method described above, it is possible to implement other +custom authentication mechanisms using the ``REMOTE_USER`` WSGI environment +variable. + +.. ATTENTION:: + + Please note that even if it is possible to develop a custom authentication + module, it is preferable to use the modules in the HTTPD server. Such + authentication modules in webservers like Apache have normally undergone + years of development and use in production systems and are actively + maintained upstream. Developing a custom authentication module that + implements the same authentication as an existing Apache module likely + introduces a higher security risk. + +If you find you must implement a custom authentication mechanism, you will need +to develop a custom WSGI middleware pipeline component. This middleware should +set the environment variable ``REMOTE_USER`` to the authenticated username. +Keystone then will assume that the user has been already authenticated upstream +and will not try to authenticate it. However, as with HTTPD authentication, the +user must exist in advance in the identity backend so that a proper token can +be issued. + +Your code should set the ``REMOTE_USER`` if the user is properly authenticated, +following the semantics below: + +.. code-block:: python + + from keystone.common import wsgi + from keystone import exception + + class MyMiddlewareAuth(wsgi.Middleware): + def __init__(self, *args, **kwargs): + super(MyMiddlewareAuth, self).__init__(*args, **kwargs) + + def process_request(self, request): + if request.environ.get('REMOTE_USER', None) is not None: + # Assume that it is authenticated upstream + return self.application + + if not self.is_auth_applicable(request): + # Not applicable + return self.application + + username = self.do_auth(request) + if username is not None: + # User is authenticated + request.environ['REMOTE_USER'] = username + else: + # User is not authenticated, render exception + raise exception.Unauthorized("Invalid user") + + +Pipeline configuration +---------------------- + +Once you have your WSGI middleware component developed you have to add it to +your pipeline. The first step is to add the middleware to your configuration +file. Assuming that your middleware module is +``keystone.middleware.MyMiddlewareAuth``, you can configure it in your +``keystone-paste.ini`` as:: + + [filter:my_auth] + paste.filter_factory = keystone.middleware.MyMiddlewareAuth.factory + +The second step is to add your middleware to the pipeline. The exact place +where you should place it will depend on your code (i.e. if you need for +example that the request body is converted from JSON before perform the +authentication you should place it after the ``json_body`` filter) but it +should be set before the ``public_service`` (for the ``public_api`` pipeline) +or ``admin_service`` (for the ``admin_api`` pipeline), since they consume +authentication. + +For example, if the original pipeline looks like this:: + + [pipeline:public_api] + pipeline = url_normalize token_auth admin_token_auth json_body debug ec2_extension user_crud_extension public_service + +Your modified pipeline might then look like this:: + + [pipeline:public_api] + pipeline = url_normalize token_auth admin_token_auth json_body my_auth debug ec2_extension user_crud_extension public_service -- cgit 1.2.3-korg