]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Addressing comments from Ziad and Somik
authorSalvatore Orlando <salvatore.orlando@eu.citrix.com>
Tue, 23 Aug 2011 16:47:45 +0000 (17:47 +0100)
committerSalvatore Orlando <salvatore.orlando@eu.citrix.com>
Tue, 23 Aug 2011 16:47:45 +0000 (17:47 +0100)
README
etc/quantum.conf
quantum/common/authentication.py
quantum/common/authorization.py

diff --git a/README b/README
index c7877ef6f6d2594ac81042ddadf3b4c7b7737abb..be695302aef41c5548b3ff05c76bab892094ad1d 100644 (file)
--- a/README
+++ b/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
index fe6ce8f8434c3fad794ac602c9553340dadeb36b..ab63496390f0c10331e76b98a1bd66fa2d7d5dff 100644 (file)
@@ -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
index 3f4b52328302b39c3fb218e889fe288331927782..6f849249bb4e5d2d99107f11e9eafec1bbd0726d 100755 (executable)
@@ -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 """
index 6fb59780ae80d4458f415b11436a8cad2f3112e3..408b5c6fce7a4a5d4164e8f5043c829b2e88d88a 100644 (file)
@@ -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)