]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
11fdf7f2 | 3 | |
9f95a23c | 4 | #pragma once |
11fdf7f2 TL |
5 | |
6 | #include "rgw_auth.h" | |
7 | #include "rgw_auth_filters.h" | |
f67539c2 | 8 | #include "rgw_rest.h" |
11fdf7f2 TL |
9 | #include "rgw_sts.h" |
10 | #include "rgw_web_idp.h" | |
f91f0fd5 TL |
11 | #include "jwt-cpp/jwt.h" |
12 | #include "rgw_oidc_provider.h" | |
11fdf7f2 | 13 | |
9f95a23c | 14 | namespace rgw::auth::sts { |
11fdf7f2 TL |
15 | |
16 | class WebTokenEngine : public rgw::auth::Engine { | |
17 | CephContext* const cct; | |
f91f0fd5 | 18 | RGWCtl* const ctl; |
11fdf7f2 TL |
19 | |
20 | using result_t = rgw::auth::Engine::result_t; | |
21 | using token_t = rgw::web_idp::WebTokenClaims; | |
22 | ||
23 | const rgw::auth::TokenExtractor* const extractor; | |
24 | const rgw::auth::WebIdentityApplier::Factory* const apl_factory; | |
25 | ||
26 | bool is_applicable(const std::string& token) const noexcept; | |
27 | ||
f91f0fd5 TL |
28 | bool is_client_id_valid(vector<string>& client_ids, const string& client_id) const; |
29 | ||
30 | bool is_cert_valid(const vector<string>& thumbprints, const string& cert) const; | |
31 | ||
b3b6e05e | 32 | boost::optional<RGWOIDCProvider> get_provider(const DoutPrefixProvider *dpp, const string& role_arn, const string& iss) const; |
f91f0fd5 | 33 | |
f67539c2 TL |
34 | std::string get_role_tenant(const string& role_arn) const; |
35 | ||
f91f0fd5 | 36 | boost::optional<WebTokenEngine::token_t> |
f67539c2 | 37 | get_from_jwt(const DoutPrefixProvider* dpp, const std::string& token, const req_state* const s, optional_yield y) const; |
f91f0fd5 | 38 | |
f67539c2 | 39 | void validate_signature (const DoutPrefixProvider* dpp, const jwt::decoded_jwt& decoded, const string& algorithm, const string& iss, const vector<string>& thumbprints, optional_yield y) const; |
11fdf7f2 TL |
40 | |
41 | result_t authenticate(const DoutPrefixProvider* dpp, | |
42 | const std::string& token, | |
f67539c2 | 43 | const req_state* s, optional_yield y) const; |
11fdf7f2 TL |
44 | |
45 | public: | |
46 | WebTokenEngine(CephContext* const cct, | |
f91f0fd5 | 47 | RGWCtl* const ctl, |
11fdf7f2 TL |
48 | const rgw::auth::TokenExtractor* const extractor, |
49 | const rgw::auth::WebIdentityApplier::Factory* const apl_factory) | |
50 | : cct(cct), | |
f91f0fd5 | 51 | ctl(ctl), |
11fdf7f2 TL |
52 | extractor(extractor), |
53 | apl_factory(apl_factory) { | |
54 | } | |
55 | ||
56 | const char* get_name() const noexcept override { | |
57 | return "rgw::auth::sts::WebTokenEngine"; | |
58 | } | |
59 | ||
f67539c2 TL |
60 | result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override { |
61 | return authenticate(dpp, extractor->get_token(s), s, y); | |
11fdf7f2 TL |
62 | } |
63 | }; /* class WebTokenEngine */ | |
64 | ||
65 | class DefaultStrategy : public rgw::auth::Strategy, | |
66 | public rgw::auth::TokenExtractor, | |
67 | public rgw::auth::WebIdentityApplier::Factory { | |
9f95a23c TL |
68 | RGWCtl* const ctl; |
69 | ImplicitTenants& implicit_tenant_context; | |
11fdf7f2 TL |
70 | |
71 | /* The engine. */ | |
72 | const WebTokenEngine web_token_engine; | |
73 | ||
74 | using aplptr_t = rgw::auth::IdentityApplier::aplptr_t; | |
75 | ||
76 | /* The method implements TokenExtractor for Web Token in req_state. */ | |
77 | std::string get_token(const req_state* const s) const override { | |
78 | return s->info.args.get("WebIdentityToken"); | |
79 | } | |
80 | ||
81 | aplptr_t create_apl_web_identity( CephContext* cct, | |
82 | const req_state* s, | |
f91f0fd5 | 83 | const string& role_session, |
f67539c2 | 84 | const string& role_tenant, |
11fdf7f2 | 85 | const rgw::web_idp::WebTokenClaims& token) const override { |
9f95a23c | 86 | auto apl = rgw::auth::add_sysreq(cct, ctl, s, |
f67539c2 | 87 | rgw::auth::WebIdentityApplier(cct, ctl, role_session, role_tenant, token)); |
11fdf7f2 TL |
88 | return aplptr_t(new decltype(apl)(std::move(apl))); |
89 | } | |
90 | ||
91 | public: | |
92 | DefaultStrategy(CephContext* const cct, | |
9f95a23c TL |
93 | ImplicitTenants& implicit_tenant_context, |
94 | RGWCtl* const ctl) | |
95 | : ctl(ctl), | |
96 | implicit_tenant_context(implicit_tenant_context), | |
f91f0fd5 | 97 | web_token_engine(cct, ctl, |
11fdf7f2 TL |
98 | static_cast<rgw::auth::TokenExtractor*>(this), |
99 | static_cast<rgw::auth::WebIdentityApplier::Factory*>(this)) { | |
100 | /* When the constructor's body is being executed, all member engines | |
101 | * should be initialized. Thus, we can safely add them. */ | |
102 | using Control = rgw::auth::Strategy::Control; | |
103 | add_engine(Control::SUFFICIENT, web_token_engine); | |
104 | } | |
105 | ||
106 | const char* get_name() const noexcept override { | |
107 | return "rgw::auth::sts::DefaultStrategy"; | |
108 | } | |
109 | }; | |
110 | ||
9f95a23c | 111 | } // namespace rgw::auth::sts |
11fdf7f2 TL |
112 | |
113 | class RGWREST_STS : public RGWRESTOp { | |
114 | protected: | |
115 | STS::STSService sts; | |
116 | public: | |
117 | RGWREST_STS() = default; | |
f67539c2 | 118 | int verify_permission(optional_yield y) override; |
11fdf7f2 TL |
119 | void send_response() override; |
120 | }; | |
121 | ||
122 | class RGWSTSAssumeRoleWithWebIdentity : public RGWREST_STS { | |
123 | protected: | |
124 | string duration; | |
125 | string providerId; | |
126 | string policy; | |
127 | string roleArn; | |
128 | string roleSessionName; | |
129 | string sub; | |
130 | string aud; | |
131 | string iss; | |
132 | public: | |
133 | RGWSTSAssumeRoleWithWebIdentity() = default; | |
f67539c2 | 134 | void execute(optional_yield y) override; |
11fdf7f2 TL |
135 | int get_params(); |
136 | const char* name() const override { return "assume_role_web_identity"; } | |
137 | RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE_WEB_IDENTITY; } | |
138 | }; | |
139 | ||
140 | class RGWSTSAssumeRole : public RGWREST_STS { | |
141 | protected: | |
142 | string duration; | |
143 | string externalId; | |
144 | string policy; | |
145 | string roleArn; | |
146 | string roleSessionName; | |
147 | string serialNumber; | |
148 | string tokenCode; | |
149 | public: | |
150 | RGWSTSAssumeRole() = default; | |
f67539c2 | 151 | void execute(optional_yield y) override; |
11fdf7f2 TL |
152 | int get_params(); |
153 | const char* name() const override { return "assume_role"; } | |
154 | RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE; } | |
155 | }; | |
156 | ||
157 | class RGWSTSGetSessionToken : public RGWREST_STS { | |
158 | protected: | |
159 | string duration; | |
160 | string serialNumber; | |
161 | string tokenCode; | |
162 | public: | |
163 | RGWSTSGetSessionToken() = default; | |
f67539c2 TL |
164 | void execute(optional_yield y) override; |
165 | int verify_permission(optional_yield y) override; | |
11fdf7f2 TL |
166 | int get_params(); |
167 | const char* name() const override { return "get_session_token"; } | |
168 | RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; } | |
169 | }; | |
170 | ||
171 | class RGW_Auth_STS { | |
172 | public: | |
173 | static int authorize(const DoutPrefixProvider *dpp, | |
9f95a23c | 174 | rgw::sal::RGWRadosStore *store, |
11fdf7f2 | 175 | const rgw::auth::StrategyRegistry& auth_registry, |
f67539c2 | 176 | struct req_state *s, optional_yield y); |
11fdf7f2 TL |
177 | }; |
178 | ||
179 | class RGWHandler_REST_STS : public RGWHandler_REST { | |
180 | const rgw::auth::StrategyRegistry& auth_registry; | |
eafe8130 | 181 | const string& post_body; |
11fdf7f2 TL |
182 | RGWOp *op_post() override; |
183 | void rgw_sts_parse_input(); | |
184 | public: | |
185 | ||
186 | static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format); | |
187 | ||
eafe8130 | 188 | RGWHandler_REST_STS(const rgw::auth::StrategyRegistry& auth_registry, const string& post_body="") |
11fdf7f2 | 189 | : RGWHandler_REST(), |
eafe8130 TL |
190 | auth_registry(auth_registry), |
191 | post_body(post_body) {} | |
11fdf7f2 TL |
192 | ~RGWHandler_REST_STS() override = default; |
193 | ||
9f95a23c | 194 | int init(rgw::sal::RGWRadosStore *store, |
11fdf7f2 TL |
195 | struct req_state *s, |
196 | rgw::io::BasicClient *cio) override; | |
f67539c2 TL |
197 | int authorize(const DoutPrefixProvider* dpp, optional_yield y) override; |
198 | int postauth_init(optional_yield y) override { return 0; } | |
11fdf7f2 TL |
199 | }; |
200 | ||
201 | class RGWRESTMgr_STS : public RGWRESTMgr { | |
202 | public: | |
203 | RGWRESTMgr_STS() = default; | |
204 | ~RGWRESTMgr_STS() override = default; | |
205 | ||
206 | RGWRESTMgr *get_resource_mgr(struct req_state* const s, | |
207 | const std::string& uri, | |
208 | std::string* const out_uri) override { | |
209 | return this; | |
210 | } | |
211 | ||
f67539c2 TL |
212 | RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, |
213 | struct req_state*, | |
11fdf7f2 TL |
214 | const rgw::auth::StrategyRegistry&, |
215 | const std::string&) override; | |
216 | }; |