Accept STS and IAM services from Ceph Obj Gateway
Ceph Object Gateway can use keystone for authenticating user requests to its S3-compatible API, but recent versions also provide two other AWS-compatible APIs for managing user access: Security Token Service (STS) and Identity and Access Management (IAM). These attempt to authenticate requests with Keystone but always receive 403 Access Denied because _calculate_signature_v4() in api/s3tokens.py only accepts "s3" as the service name. This patch accepts any of "s3" or "sts" or "iam" as valid service names. Change-Id: I69f16ed55dd9852859307b701a8391ba1e71c042 Closes-Bug: #1897280
This commit is contained in:
parent
1e7ecca881
commit
36d6fc7f8f
@ -56,7 +56,10 @@ def _calculate_signature_v4(string_to_sign, secret_key):
|
||||
if len(parts) != 4 or parts[0] != b'AWS4-HMAC-SHA256':
|
||||
raise exception.Unauthorized(message=_('Invalid EC2 signature.'))
|
||||
scope = parts[2].split(b'/')
|
||||
if len(scope) != 4 or scope[2] != b's3' or scope[3] != b'aws4_request':
|
||||
if len(scope) != 4 or scope[3] != b'aws4_request':
|
||||
raise exception.Unauthorized(message=_('Invalid EC2 signature.'))
|
||||
allowed_services = [b's3', b'iam', b'sts']
|
||||
if scope[2] not in allowed_services:
|
||||
raise exception.Unauthorized(message=_('Invalid EC2 signature.'))
|
||||
|
||||
def _sign(key, msg):
|
||||
|
@ -121,9 +121,40 @@ class S3ContribCore(test_v3.RestfulTestCase):
|
||||
self.assertIsNone(s3tokens.S3Resource._check_signature(
|
||||
creds_ref, credentials))
|
||||
|
||||
def test_good_iam_signature_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
credentials = {'token':
|
||||
'QVdTNC1ITUFDLVNIQTI1NgoyMDE1MDgyNFQxMTIwNDFaCjIw'
|
||||
'MTUwODI0L1JlZ2lvbk9uZS9pYW0vYXdzNF9yZXF1ZXN0CmYy'
|
||||
'MjE1NTgwZWViOWExNjczNTFiZDkzZTg2YzNiNmYwNGE5Mjhm'
|
||||
'NWM1NTIwYTM5MzVhNDUzNTQwYTA5NTY0YjU=',
|
||||
'signature':
|
||||
'db4e15b3040f6afaa9d9d16002de2fc3425b'
|
||||
'eea0c6ea8c1b2bb674f052030b7d'}
|
||||
|
||||
self.assertIsNone(s3tokens.S3Resource._check_signature(
|
||||
creds_ref, credentials))
|
||||
|
||||
def test_good_sts_signature_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
credentials = {'token':
|
||||
'QVdTNC1ITUFDLVNIQTI1NgoyMDE1MDgyNFQxMTIwNDFaCjIw'
|
||||
'MTUwODI0L1JlZ2lvbk9uZS9zdHMvYXdzNF9yZXF1ZXN0CmYy'
|
||||
'MjE1NTgwZWViOWExNjczNTFiZDkzZTg2YzNiNmYwNGE5Mjhm'
|
||||
'NWM1NTIwYTM5MzVhNDUzNTQwYTA5NTY0YjU=',
|
||||
'signature':
|
||||
'3aa0b6f1414b92b2a32584068f83c6d09b7f'
|
||||
'daa11d4ea58912bbf1d8616ef56d'}
|
||||
|
||||
self.assertIsNone(s3tokens.S3Resource._check_signature(
|
||||
creds_ref, credentials))
|
||||
|
||||
def test_bad_signature_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
# the signature is wrong on an otherwise correctly formed token
|
||||
credentials = {'token':
|
||||
'QVdTNC1ITUFDLVNIQTI1NgoyMDE1MDgyNFQxMTIwNDFaCjIw'
|
||||
'MTUwODI0L1JlZ2lvbk9uZS9zMy9hd3M0X3JlcXVlc3QKZjIy'
|
||||
@ -135,6 +166,57 @@ class S3ContribCore(test_v3.RestfulTestCase):
|
||||
s3tokens.S3Resource._check_signature,
|
||||
creds_ref, credentials)
|
||||
|
||||
def test_bad_service_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
# use 'bad' as the service scope instead of a recognised service
|
||||
credentials = {'token':
|
||||
'QVdTNC1ITUFDLVNIQTI1NgoyMDE1MDgyNFQxMTIwNDFaCjIw'
|
||||
'MTUwODI0L1JlZ2lvbk9uZS9iYWQvYXdzNF9yZXF1ZXN0CmYy'
|
||||
'MjE1NTgwZWViOWExNjczNTFiZDkzZTg2YzNiNmYwNGE5Mjhm'
|
||||
'NWM1NTIwYTM5MzVhNDUzNTQwYTA5NTY0YjU=',
|
||||
'signature':
|
||||
'1a2dec50eb1bba97887d1103c2ead6a39911'
|
||||
'98c4be2537cf14d40b64cceb888b'}
|
||||
|
||||
self.assertRaises(exception.Unauthorized,
|
||||
s3tokens.S3Resource._check_signature,
|
||||
creds_ref, credentials)
|
||||
|
||||
def test_bad_signing_key_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
# signed with aws4_badrequest instead of aws4_request
|
||||
credentials = {'token':
|
||||
'QVdTNC1ITUFDLVNIQTI1NgoyMDE1MDgyNFQxMTIwNDFaCjIw'
|
||||
'MTUwODI0L1JlZ2lvbk9uZS9zMy9hd3M0X3JlcXVlc3QKZjIy'
|
||||
'MTU1ODBlZWI5YTE2NzM1MWJkOTNlODZjM2I2ZjA0YTkyOGY1'
|
||||
'YzU1MjBhMzkzNWE0NTM1NDBhMDk1NjRiNQ==',
|
||||
'signature':
|
||||
'52d02211a3767d00b2104ab28c9859003b0e'
|
||||
'9c8735cd10de7975f3b1212cca41'}
|
||||
|
||||
self.assertRaises(exception.Unauthorized,
|
||||
s3tokens.S3Resource._check_signature,
|
||||
creds_ref, credentials)
|
||||
|
||||
def test_bad_short_scope_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
# credential scope has too few parts, missing final /aws4_request
|
||||
credentials = {'token':
|
||||
'QVdTNC1ITUFDLVNIQTI1NgoyMDE1MDgyNFQxMTIwNDFaCjIw'
|
||||
'MTUwODI0L1JlZ2lvbk9uZS9zMwpmMjIxNTU4MGVlYjlhMTY3'
|
||||
'MzUxYmQ5M2U4NmMzYjZmMDRhOTI4ZjVjNTUyMGEzOTM1YTQ1'
|
||||
'MzU0MGEwOTU2NGI1',
|
||||
'signature':
|
||||
'28a075f1ee41e96c431153914998443ff0f5'
|
||||
'5fe93d31b37181f13ff4865942a2'}
|
||||
|
||||
self.assertRaises(exception.Unauthorized,
|
||||
s3tokens.S3Resource._check_signature,
|
||||
creds_ref, credentials)
|
||||
|
||||
def test_bad_token_v4(self):
|
||||
creds_ref = {'secret':
|
||||
u'e7a7a2240136494986991a6598d9fb9f'}
|
||||
|
7
releasenotes/notes/bug-1897280-e7065c4368a325ad.yaml
Normal file
7
releasenotes/notes/bug-1897280-e7065c4368a325ad.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
[ `Bug 1897230 <https://launchpad.net/bugs/1897280>`_]
|
||||
Allows s3 tokens with service types sts and iam to authenticate. This
|
||||
is necessary when using assumed role features of Ceph object storage and
|
||||
keystone is providing the authentication service for Rados Gateway.
|
Loading…
x
Reference in New Issue
Block a user