-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathAwsIamAuthenticationStrategy.php
More file actions
123 lines (104 loc) · 3.31 KB
/
AwsIamAuthenticationStrategy.php
File metadata and controls
123 lines (104 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
namespace Vault\AuthenticationStrategies;
use Aws\Middleware;
use Aws\Sts\StsClient;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Client\ClientExceptionInterface;
use Vault\Exceptions\AuthenticationException;
use Vault\ResponseModels\Auth;
/**
* Class AwsIamAuthenticationStrategy
*
* @package Vault\AuthenticationStrategy
*/
class AwsIamAuthenticationStrategy extends AbstractAuthenticationStrategy
{
/**
* @var string
*/
protected $methodPathSegment = 'aws';
/** @var string */
private $role;
/** @var string */
private $region;
/** @var ?string */
private $serverId;
/** @var StsClient|null */
private $stsClient;
/**
* @param string $role The name of the vault role
* @param string $region The AWS region to use
* @param ?string $vaultServerId If set, this string is used as X-Vault-AWS-IAM-Server-ID, to protect against replay attacks
* @param ?StsClient $stsClient Custom instance of StsClient
*/
public function __construct(
$role,
$region,
$vaultServerId = null,
$stsClient = null
) {
$this->role = $role;
$this->region = $region;
$this->serverId = $vaultServerId;
$this->stsClient = $stsClient;
}
/**
* Returns auth for further interactions with Vault.
*
* @return Auth
* @throws AuthenticationException
* @throws ClientExceptionInterface
*/
public function authenticate(): Auth
{
if (!$this->methodPathSegment) {
throw new AuthenticationException('methodPathSegment must be set before usage');
}
if (!$this->stsClient) {
$this->stsClient = new StsClient([
'region' => $this->region,
'version' => 'latest',
'sts_regional_endpoints' => 'regional',
]);
}
// Creating a signed command, to get the parameters for the actual login-request to vault
$command = $this->stsClient->getCommand('GetCallerIdentity');
if ($this->serverId) {
$command->getHandlerList()->appendBuild(
Middleware::mapRequest(function (RequestInterface $request) {
return $request->withHeader('X-Vault-AWS-IAM-Server-ID', $this->serverId);
}),
'add-header'
);
}
$request = \Aws\serialize($command);
$response = $this->client->write(
sprintf('/auth/%s/login', $this->methodPathSegment),
[
'role' => $this->role,
'iam_http_request_method' => $request->getMethod(),
'iam_request_url' => base64_encode($request->getUri()),
'iam_request_body' => base64_encode($request->getBody()),
'iam_request_headers' => base64_encode(json_encode($request->getHeaders())),
]
);
return $response->getAuth();
}
/**
* @return string
*/
public function getMethodPathSegment(): string
{
return $this->methodPathSegment;
}
/**
* @param string $methodPathSegment
*
* @return static
*/
public function setMethodPathSegment(string $methodPathSegment)
{
$this->methodPathSegment = $methodPathSegment;
return $this;
}
}