Addressing comments from Ziad and Somik
This commit is contained in:
parent
d3ff660f78
commit
667dab4e83
37
README
37
README
@ -84,6 +84,43 @@ $ export TENANT=t1
|
||||
$ PYTHONPATH=. python quantum/cli.py -v create_net $TENANT network1
|
||||
Created a new Virtual Network with ID:e754e7c0-a8eb-40e5-861a-b182d30c3441
|
||||
|
||||
# -- Authentication and Authorization
|
||||
|
||||
Requests to Quantum API are authenticated with the Keystone identity service
|
||||
using a token-based authentication protocol.
|
||||
|
||||
A user should first authenticate with Keystone, supplying user credentials;
|
||||
the Keystone service will return an authentication token, together with
|
||||
informations concerning token expirations and endpoint where that token can
|
||||
be used.
|
||||
|
||||
The authentication token must be included in every request for the Quantum
|
||||
API, in the 'X_AUTH_TOKEN' header. Quantum will look for the authentication
|
||||
token in this header, and validate it with the Keystone service.
|
||||
|
||||
In order to validate authentication tokens, Quantum uses Keystone's
|
||||
administrative API. It therefore requires credentials for an administrative
|
||||
user, which can be specified in Quantum's configuration file
|
||||
(etc/quantum.conf)
|
||||
Either username and password, or an authentication token for an administrative
|
||||
user can be specified in the configuration file:
|
||||
|
||||
- Credentials:
|
||||
|
||||
admin_user = admin
|
||||
admin_password = secrete
|
||||
|
||||
- Admin token:
|
||||
|
||||
admin_token = 9a82c95a-99e9-4c3a-b5ee-199f6ba7ff04
|
||||
|
||||
As of the current release, any user for a tenant is allowed to perform
|
||||
every operation on the networks owned by the tenant itself, except for
|
||||
plugging interfaces. In order to perform such operation, the user must have
|
||||
the Quantum:NetworkAdmin roles. Roles can be configured in Keystone using
|
||||
the administrative API.
|
||||
|
||||
|
||||
# -- Writing your own Quantum plug-in
|
||||
|
||||
If you wish the write your own Quantum plugin, please refer to some concrete as
|
||||
|
@ -20,10 +20,11 @@ use = egg:Paste#urlmap
|
||||
/v0.1: quantumapi
|
||||
|
||||
[pipeline:quantumapi]
|
||||
# To enable keystone integration comment the following line and
|
||||
# To disable keystone integration comment the following line and
|
||||
# uncomment the next one
|
||||
pipeline = extensions quantumapiapp
|
||||
#pipeline = authN authZ extensions quantumapiapp
|
||||
pipeline = authN authZ extensions quantumapiapp
|
||||
#pipeline = extensions quantumapiapp
|
||||
|
||||
|
||||
[filter:authN]
|
||||
paste.filter_factory = quantum.common.authentication:filter_factory
|
||||
|
@ -223,13 +223,11 @@ class AuthProtocol(object):
|
||||
|
||||
def _reject_request(self):
|
||||
"""Redirect client to auth server"""
|
||||
return HTTPUseProxy(location=self.auth_location)(self.env,
|
||||
self.start_response)
|
||||
return HTTPUnauthorized()(self.env, self.start_response)
|
||||
|
||||
def _reject_claims(self):
|
||||
"""Client sent bad claims"""
|
||||
return HTTPUnauthorized()(self.env,
|
||||
self.start_response)
|
||||
return HTTPUnauthorized()(self.env, self.start_response)
|
||||
|
||||
def _validate_claims(self, claims):
|
||||
"""Validate claims, and provide identity information if applicable """
|
||||
|
@ -31,6 +31,9 @@ import logging
|
||||
from webob.exc import HTTPUnauthorized, HTTPForbidden
|
||||
|
||||
LOG = logging.getLogger('quantum.common.authorization')
|
||||
TENANT_HEADER = "HTTP_X_TENANT"
|
||||
ROLE_HEADER = "HTTP_X_ROLE"
|
||||
ADMIN_ROLE = "Quantum:NetworkAdmin"
|
||||
|
||||
|
||||
#TODO(salvatore-orlando): This class should extend Middleware class
|
||||
@ -54,12 +57,11 @@ class QuantumAuthorization(object):
|
||||
# should already have been authenticated with Keystone
|
||||
self.headers = req.copy()
|
||||
LOG.debug("Looking for X_TENANT header")
|
||||
LOG.debug("Headers:%s" % self.headers)
|
||||
if not "HTTP_X_TENANT" in self.headers:
|
||||
if not TENANT_HEADER in self.headers:
|
||||
# This is bad, very bad
|
||||
return self._reject()
|
||||
LOG.debug("X_TENANT header found:%s", self.headers['HTTP_X_TENANT'])
|
||||
auth_tenant_id = self.headers['HTTP_X_TENANT']
|
||||
LOG.debug("X_TENANT header found:%s", self.headers[TENANT_HEADER])
|
||||
auth_tenant_id = self.headers[TENANT_HEADER]
|
||||
path = self.req['PATH_INFO']
|
||||
parts = path.split('/')
|
||||
LOG.debug("Request parts:%s", parts)
|
||||
@ -70,7 +72,19 @@ class QuantumAuthorization(object):
|
||||
if auth_tenant_id != req_tenant_id:
|
||||
# This is bad, very bad
|
||||
return self._forbid()
|
||||
|
||||
# Are you trying to operate on an attachment?
|
||||
# If yes, you must be Quantum:NetworkAdmin
|
||||
if parts[len(parts) - 1] == "attachment":
|
||||
LOG.debug("Looking for X_ROLE header")
|
||||
LOG.debug("Headers:%s", self.headers)
|
||||
if not ROLE_HEADER in self.headers:
|
||||
#This is bad as you definetely are not an administrator
|
||||
return self._forbid()
|
||||
LOG.debug("X_ROLE header found:%s", self.headers[ROLE_HEADER])
|
||||
roles = self.headers[ROLE_HEADER].split(',')
|
||||
if not ADMIN_ROLE in roles:
|
||||
# Sorry, you're not and admin
|
||||
return self._forbid()
|
||||
# Okay, authorize it - pass downstream
|
||||
return self.app(self.req, self.start_response)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user