]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_sts.h
import ceph pacific 16.2.5
[ceph.git] / ceph / src / rgw / rgw_rest_sts.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #pragma once
5
6 #include "rgw_auth.h"
7 #include "rgw_auth_filters.h"
8 #include "rgw_rest.h"
9 #include "rgw_sts.h"
10 #include "rgw_web_idp.h"
11 #include "jwt-cpp/jwt.h"
12 #include "rgw_oidc_provider.h"
13
14 namespace rgw::auth::sts {
15
16 class WebTokenEngine : public rgw::auth::Engine {
17 CephContext* const cct;
18 RGWCtl* const ctl;
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
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
32 boost::optional<RGWOIDCProvider> get_provider(const DoutPrefixProvider *dpp, const string& role_arn, const string& iss) const;
33
34 std::string get_role_tenant(const string& role_arn) const;
35
36 boost::optional<WebTokenEngine::token_t>
37 get_from_jwt(const DoutPrefixProvider* dpp, const std::string& token, const req_state* const s, optional_yield y) const;
38
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;
40
41 result_t authenticate(const DoutPrefixProvider* dpp,
42 const std::string& token,
43 const req_state* s, optional_yield y) const;
44
45 public:
46 WebTokenEngine(CephContext* const cct,
47 RGWCtl* const ctl,
48 const rgw::auth::TokenExtractor* const extractor,
49 const rgw::auth::WebIdentityApplier::Factory* const apl_factory)
50 : cct(cct),
51 ctl(ctl),
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
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);
62 }
63 }; /* class WebTokenEngine */
64
65 class DefaultStrategy : public rgw::auth::Strategy,
66 public rgw::auth::TokenExtractor,
67 public rgw::auth::WebIdentityApplier::Factory {
68 RGWCtl* const ctl;
69 ImplicitTenants& implicit_tenant_context;
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,
83 const string& role_session,
84 const string& role_tenant,
85 const rgw::web_idp::WebTokenClaims& token) const override {
86 auto apl = rgw::auth::add_sysreq(cct, ctl, s,
87 rgw::auth::WebIdentityApplier(cct, ctl, role_session, role_tenant, token));
88 return aplptr_t(new decltype(apl)(std::move(apl)));
89 }
90
91 public:
92 DefaultStrategy(CephContext* const cct,
93 ImplicitTenants& implicit_tenant_context,
94 RGWCtl* const ctl)
95 : ctl(ctl),
96 implicit_tenant_context(implicit_tenant_context),
97 web_token_engine(cct, ctl,
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
111 } // namespace rgw::auth::sts
112
113 class RGWREST_STS : public RGWRESTOp {
114 protected:
115 STS::STSService sts;
116 public:
117 RGWREST_STS() = default;
118 int verify_permission(optional_yield y) override;
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;
134 void execute(optional_yield y) override;
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;
151 void execute(optional_yield y) override;
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;
164 void execute(optional_yield y) override;
165 int verify_permission(optional_yield y) override;
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,
174 rgw::sal::RGWRadosStore *store,
175 const rgw::auth::StrategyRegistry& auth_registry,
176 struct req_state *s, optional_yield y);
177 };
178
179 class RGWHandler_REST_STS : public RGWHandler_REST {
180 const rgw::auth::StrategyRegistry& auth_registry;
181 const string& post_body;
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
188 RGWHandler_REST_STS(const rgw::auth::StrategyRegistry& auth_registry, const string& post_body="")
189 : RGWHandler_REST(),
190 auth_registry(auth_registry),
191 post_body(post_body) {}
192 ~RGWHandler_REST_STS() override = default;
193
194 int init(rgw::sal::RGWRadosStore *store,
195 struct req_state *s,
196 rgw::io::BasicClient *cio) override;
197 int authorize(const DoutPrefixProvider* dpp, optional_yield y) override;
198 int postauth_init(optional_yield y) override { return 0; }
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
212 RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store,
213 struct req_state*,
214 const rgw::auth::StrategyRegistry&,
215 const std::string&) override;
216 };