IAM validation: Now supports SSM requests (#6785)
This commit is contained in:
parent
3545d38595
commit
ca9d8fc420
@ -149,6 +149,7 @@ class ActionAuthenticatorMixin(object):
|
||||
method=self.method, # type: ignore[attr-defined]
|
||||
path=path,
|
||||
data=self.data, # type: ignore[attr-defined]
|
||||
body=self.body, # type: ignore[attr-defined]
|
||||
headers=self.headers, # type: ignore[attr-defined]
|
||||
)
|
||||
iam_request.check_signature()
|
||||
|
@ -174,6 +174,7 @@ class IAMRequestBase(object, metaclass=ABCMeta):
|
||||
method: str,
|
||||
path: str,
|
||||
data: Dict[str, str],
|
||||
body: bytes,
|
||||
headers: Dict[str, str],
|
||||
):
|
||||
log.debug(
|
||||
@ -183,6 +184,7 @@ class IAMRequestBase(object, metaclass=ABCMeta):
|
||||
self._method = method
|
||||
self._path = path
|
||||
self._data = data
|
||||
self._body = body
|
||||
self._headers = headers
|
||||
credential_scope = self._get_string_between(
|
||||
"Credential=", ",", self._headers["Authorization"]
|
||||
@ -190,13 +192,14 @@ class IAMRequestBase(object, metaclass=ABCMeta):
|
||||
credential_data = credential_scope.split("/")
|
||||
self._region = credential_data[2]
|
||||
self._service = credential_data[3]
|
||||
action_from_request = self._action_from_request()
|
||||
self._action = (
|
||||
self._service
|
||||
+ ":"
|
||||
+ (
|
||||
self._data["Action"][0]
|
||||
if isinstance(self._data["Action"], list)
|
||||
else self._data["Action"]
|
||||
action_from_request[0]
|
||||
if isinstance(action_from_request, list)
|
||||
else action_from_request
|
||||
)
|
||||
)
|
||||
try:
|
||||
@ -208,6 +211,11 @@ class IAMRequestBase(object, metaclass=ABCMeta):
|
||||
except CreateAccessKeyFailure as e:
|
||||
self._raise_invalid_access_key(e.reason)
|
||||
|
||||
def _action_from_request(self) -> str:
|
||||
if "X-Amz-Target" in self._headers:
|
||||
return self._headers["X-Amz-Target"].split(".")[-1]
|
||||
return self._data["Action"]
|
||||
|
||||
def check_signature(self) -> None:
|
||||
original_signature = self._get_string_between(
|
||||
"Signature=", ",", self._headers["Authorization"]
|
||||
@ -267,7 +275,10 @@ class IAMRequestBase(object, metaclass=ABCMeta):
|
||||
).split(";")
|
||||
headers = self._create_headers_for_aws_request(signed_headers, self._headers)
|
||||
request = AWSRequest(
|
||||
method=self._method, url=self._path, data=self._data, headers=headers
|
||||
method=self._method,
|
||||
url=self._path,
|
||||
data=self._body or self._data,
|
||||
headers=headers,
|
||||
)
|
||||
request.context["timestamp"] = headers["X-Amz-Date"]
|
||||
|
||||
|
@ -5,7 +5,7 @@ from botocore.exceptions import ClientError
|
||||
|
||||
import pytest
|
||||
|
||||
from moto import mock_iam, mock_ec2, mock_s3, mock_sts, mock_elbv2, mock_rds
|
||||
from moto import mock_iam, mock_ec2, mock_s3, mock_sts, mock_ssm, mock_elbv2, mock_rds
|
||||
from moto.core import set_initial_no_auth_action_count
|
||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||
from uuid import uuid4
|
||||
@ -831,3 +831,30 @@ def test_allow_key_access_using_resource_arn() -> None:
|
||||
s3_client.put_object(Bucket="my_bucket", Key="keyname", Body=b"test")
|
||||
with pytest.raises(ClientError):
|
||||
s3_client.put_object(Bucket="my_bucket", Key="unknown", Body=b"test")
|
||||
|
||||
|
||||
@set_initial_no_auth_action_count(3)
|
||||
@mock_ssm
|
||||
@mock_iam
|
||||
def test_ssm_service():
|
||||
user_name = "test-user"
|
||||
policy_doc = {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": ["ssm:*"],
|
||||
"Effect": "Allow",
|
||||
"Resource": ["*"],
|
||||
},
|
||||
],
|
||||
}
|
||||
access_key = create_user_with_access_key_and_inline_policy(user_name, policy_doc)
|
||||
|
||||
ssmc = boto3.client(
|
||||
"ssm",
|
||||
region_name="us-east-1",
|
||||
aws_access_key_id=access_key["AccessKeyId"],
|
||||
aws_secret_access_key=access_key["SecretAccessKey"],
|
||||
)
|
||||
|
||||
ssmc.put_parameter(Name="test", Value="value", Type="String")
|
||||
|
Loading…
Reference in New Issue
Block a user