]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_sts.h
import ceph pacific 16.2.5
[ceph.git] / ceph / src / rgw / rgw_rest_sts.h
CommitLineData
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 14namespace rgw::auth::sts {
11fdf7f2
TL
15
16class 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
45public:
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
65class 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
91public:
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
113class RGWREST_STS : public RGWRESTOp {
114protected:
115 STS::STSService sts;
116public:
117 RGWREST_STS() = default;
f67539c2 118 int verify_permission(optional_yield y) override;
11fdf7f2
TL
119 void send_response() override;
120};
121
122class RGWSTSAssumeRoleWithWebIdentity : public RGWREST_STS {
123protected:
124 string duration;
125 string providerId;
126 string policy;
127 string roleArn;
128 string roleSessionName;
129 string sub;
130 string aud;
131 string iss;
132public:
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
140class RGWSTSAssumeRole : public RGWREST_STS {
141protected:
142 string duration;
143 string externalId;
144 string policy;
145 string roleArn;
146 string roleSessionName;
147 string serialNumber;
148 string tokenCode;
149public:
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
157class RGWSTSGetSessionToken : public RGWREST_STS {
158protected:
159 string duration;
160 string serialNumber;
161 string tokenCode;
162public:
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
171class RGW_Auth_STS {
172public:
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
179class 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();
184public:
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
201class RGWRESTMgr_STS : public RGWRESTMgr {
202public:
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};