The Keystone middleware architecture supports a common authentication protocol in use between the OpenStack projects. By using keystone as a common authentication and authorization mechanisms, the OpenStack project can plug in to existing authentication and authorization systems in use by existing environments.
In this document, we describe the architecture and responsibilities of the authentication middleware which acts as the internal API mechanism for OpenStack projects based on the WSGI standard.
For the architecture of keystone and its services, please see architecture. This documentation primarily describes the implementation in keystoneclient/middleware/auth_token.py (keystoneclient.middleware.auth_token.AuthProtocol)
‘Authentication’ is the process of determining that users are who they say they are. Typically, ‘authentication protocols’ such as HTTP Basic Auth, Digest Access, public key, token, etc, are used to verify a user’s identity. In this document, we define an ‘’authentication component’’ as a software module that implements an authentication protocol for an OpenStack service. OpenStack is using a token based mechanism to represent authentication and authorization.
At a high level, an authentication middleware component is a proxy that intercepts HTTP calls from clients and populates HTTP headers in the request context for other WSGI middleware or applications to use. The general flow of the middleware processing is:
Figure 1. Authentication Component
The middleware may also be configured to operated in a ‘delegated mode’. In this mode, the decision reject an unauthenticated client is delegated to the OpenStack service, as illustrated in Authentication Component (Delegated Mode).
Here, requests are forwarded to the OpenStack service with an identity status message that indicates whether the client’s identity has been confirmed or is indeterminate. It is the OpenStack service that decides whether or not a reject message should be sent to the client.
Figure 2. Authentication Component (Delegated Mode)
The middleware is intended to be used inline with OpenStack wsgi components, based on the openstack-common WSGI middleware class. It is typically deployed as a configuration element in a paste configuration pipeline of other middleware components, with the pipeline terminating in the service application. The middleware conforms to the python WSGI standard [PEP-333]. In initializing the middleware, a configuration item (which acts like a python dictionary) is passed to the middleware with relevant configuration options.
The middleware is configured within the config file of the main application as a WSGI component. Example for the auth_token middleware:
[app:myService]
paste.app_factory = myService:app_factory
[pipeline:main]
pipeline = tokenauth myService
[filter:tokenauth]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
auth_uri = http://127.0.0.1:5000/
admin_token = Super999Sekret888Password777
admin_user = admin
admin_password = SuperSekretPassword
admin_tenant_name = service
;Uncomment next line to use Swift MemcacheRing
;cache = swift.cache
;Uncomment next line and check ip:port to use memcached to cache tokens
;memcache_servers = 127.0.0.1:11211
;Uncomment next 2 lines to turn on memcache protection
;memcache_security_strategy = ENCRYPT
;memcache_secret_key = change_me
;Uncomment next 2 lines if Keystone server is validating client cert
;certfile = <path to middleware public cert>
;keyfile = <path to middleware private cert>
For services which have separate paste-deploy ini file, auth_token middleware can be alternatively configured in [keystone_authtoken] section in the main config file. For example in Nova, all middleware parameters can be removed from api-paste.ini:
[filter:authtoken]
paste.filter_factory = keystone.middleware.auth_token:filter_factory
and set in nova.conf:
[DEFAULT]
...
auth_strategy=keystone
[keystone_authtoken]
auth_host = 127.0.0.1
auth_port = 35357
auth_protocol = http
auth_uri = http://127.0.0.1:5000/
admin_user = admin
admin_password = SuperSekretPassword
admin_tenant_name = service
Note that middleware parameters in paste config take priority, they must be removed to use values in [keystone_authtoken] section.
In order to prevent excessive requests and validations, the middleware uses an in-memory cache for the tokens the keystone API returns. Keep in mind that invalidated tokens may continue to work if they are still in the token cache, so token_cache_time is configurable. For larger deployments, the middleware also supports memcache based caching.
When deploying auth_token middleware with Swift, user may elect to use Swift MemcacheRing instead of the local Keystone memcache. The Swift MemcacheRing object is passed in from the request environment and it defaults to ‘swift.cache’. However it could be different, depending on deployment. To use Swift MemcacheRing, you must provide the cache option.
When using memcached with auth_token middleware, ensure that the system time of memcached hosts is set to UTC. Memcached uses the host’s system time in determining whether a key has expired, whereas Keystone sets key expiry in UTC. The timezone used by Keystone and memcached must match if key expiry is to behave as expected.
When using memcached, we are storing user tokens and token validation information into the cache as raw data. Which means that anyone who has access to the memcache servers can read and modify data stored there. To mitigate this risk, auth_token middleware provides an option to authenticate and optionally encrypt the token data stored in the cache.
The middleware expects to find a token representing the user with the header X-Auth-Token or X-Storage-Token. X-Storage-Token is supported for swift/cloud files and for legacy Rackspace use. If the token isn’t present and the middleware is configured to not delegate auth responsibility, it will respond to the HTTP request with HTTPUnauthorized, returning the header WWW-Authenticate with the value Keystone uri=’...’ to indicate where to request a token. The auth_uri returned is configured with the middleware.
The authentication middleware extends the HTTP request with the header X-Identity-Status. If a request is successfully authenticated, the value is set to Confirmed. If the middleware is delegating the auth decision to the service, then the status is set to Invalid if the auth request was unsuccessful.
keystone.middleware.auth_token.AuthProtocol extends the request with additional information if the user has been authenticated.
[PEP-333] | pep0333 Phillip J Eby. ‘Python Web Server Gateway Interface v1.0.’’ http://www.python.org/dev/peps/pep-0333/. |