38
39
FLAGS = flags.FLAGS
39
40
LOG = logging.getLogger("nova.api")
40
flags.DEFINE_boolean('use_forwarded_for', False,
41
'Treat X-Forwarded-For as the canonical remote address. '
42
'Only enable this if you have a sanitizing proxy.')
43
41
flags.DEFINE_integer('lockout_attempts', 5,
44
42
'Number of failed auths before lockout.')
45
43
flags.DEFINE_integer('lockout_minutes', 15,
46
44
'Number of minutes to lockout if triggered.')
47
45
flags.DEFINE_integer('lockout_window', 15,
48
46
'Number of minutes for lockout window.')
47
flags.DEFINE_string('keystone_ec2_url',
48
'http://localhost:5000/v2.0/ec2tokens',
49
'URL to get token from ec2 request.')
50
flags.DECLARE('use_forwarded_for', 'nova.api.auth')
51
53
class RequestLogging(wsgi.Middleware):
143
class ToToken(wsgi.Middleware):
144
"""Authenticate an EC2 request with keystone and convert to token."""
146
@webob.dec.wsgify(RequestClass=wsgi.Request)
147
def __call__(self, req):
148
# Read request signature and access id.
150
signature = req.params['Signature']
151
access = req.params['AWSAccessKeyId']
153
raise webob.exc.HTTPBadRequest()
155
# Make a copy of args for authentication and signature verification.
156
auth_params = dict(req.params)
157
# Not part of authentication args
158
auth_params.pop('Signature')
160
# Authenticate the request.
161
client = httplib2.Http()
162
creds = {'ec2Credentials': {'access': access,
163
'signature': signature,
167
'params': auth_params,
169
headers = {'Content-Type': 'application/json'},
170
resp, content = client.request(FLAGS.keystone_ec2_url,
173
body=utils.dumps(creds))
174
# NOTE(vish): We could save a call to keystone by
175
# having keystone return token, tenant,
176
# user, and roles from this call.
177
result = utils.loads(content)
178
# TODO(vish): check for errors
179
token_id = result['auth']['token']['id']
182
req.headers['X-Auth-Token'] = token_id
183
return self.application
186
class NoAuth(wsgi.Middleware):
187
"""Add user:project as 'nova.context' to WSGI environ."""
189
@webob.dec.wsgify(RequestClass=wsgi.Request)
190
def __call__(self, req):
191
if 'AWSAccessKeyId' not in req.params:
192
raise webob.exc.HTTPBadRequest()
193
user_id, _sep, project_id = req.params['AWSAccessKeyId'].partition(':')
194
project_id = project_id or user_id
195
remote_address = getattr(req, 'remote_address', '127.0.0.1')
196
if FLAGS.use_forwarded_for:
197
remote_address = req.headers.get('X-Forwarded-For', remote_address)
198
ctx = context.RequestContext(user_id,
201
remote_address=remote_address)
203
req.environ['nova.context'] = ctx
204
return self.application
141
207
class Authenticate(wsgi.Middleware):
142
208
"""Authenticate an EC2 request and add 'nova.context' to WSGI environ."""