Skip to content

Commit 3e26494

Browse files
authored
Merge pull request ceph#53915 from pritha-srivastava/wip-rgw-sts-update-oidc-provider
rgw/iam: add AddClientIdToOIDCProvider/UpdateOidcProviderThumbprint Reviewed-by: Matt Benjamin <[email protected]> Reviewed-by: Casey Bodley <[email protected]>
2 parents 15cbae0 + 1bd56a7 commit 3e26494

File tree

10 files changed

+235
-5
lines changed

10 files changed

+235
-5
lines changed

doc/radosgw/oidc.rst

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Example::
4545
POST "<hostname>?Action=Action=CreateOpenIDConnectProvider
4646
&ThumbprintList.list.1=F7D7B3515DD0D319DD219A43A9EA727AD6065287
4747
&ClientIDList.list.1=app-profile-jsp
48-
&Url=http://localhost:8080/auth/realms/quickstart
48+
&Url=http://localhost:8080/auth/realms/quickstart"
4949

5050

5151
DeleteOpenIDConnectProvider
@@ -63,7 +63,7 @@ Request Parameters
6363

6464
Example::
6565
POST "<hostname>?Action=Action=DeleteOpenIDConnectProvider
66-
&OpenIDConnectProviderArn=arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart
66+
&OpenIDConnectProviderArn=arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"
6767

6868

6969
GetOpenIDConnectProvider
@@ -81,7 +81,7 @@ Request Parameters
8181

8282
Example::
8383
POST "<hostname>?Action=Action=GetOpenIDConnectProvider
84-
&OpenIDConnectProviderArn=arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart
84+
&OpenIDConnectProviderArn=arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart"
8585

8686
ListOpenIDConnectProviders
8787
--------------------------
@@ -95,3 +95,50 @@ None
9595

9696
Example::
9797
POST "<hostname>?Action=Action=ListOpenIDConnectProviders
98+
99+
AddClientIDToOpenIDConnectProvider
100+
----------------------------------
101+
102+
Add a client id to the list of existing client ids registered while creating an OpenIDConnectProvider.
103+
104+
Request Parameters
105+
~~~~~~~~~~~~~~~~~~
106+
107+
``OpenIDConnectProviderArn``
108+
109+
:Description: ARN of the IDP which is returned by the Create API.
110+
:Type: String
111+
112+
``ClientID``
113+
114+
:Description: Client Id to add to the existing OpenIDConnectProvider.
115+
:Type: String
116+
117+
Example::
118+
POST "<hostname>?Action=Action=AddClientIDToOpenIDConnectProvider
119+
&OpenIDConnectProviderArn=arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart
120+
&ClientID=app-jee-jsp"
121+
122+
UpdateOpenIDConnectProviderThumbprint
123+
-------------------------------------
124+
125+
Update the existing thumbprint list of an OpenIDConnectProvider with the given list.
126+
This API removes the existing thumbprint list and replaces that with the input thumbprint list.
127+
128+
Request Parameters
129+
~~~~~~~~~~~~~~~~~~
130+
131+
``OpenIDConnectProviderArn``
132+
133+
:Description: ARN of the IDP which is returned by the Create API.
134+
:Type: String
135+
136+
``ThumbprintList.member.N``
137+
138+
:Description: List of OpenID Connect IDP's server certificates' thumbprints. A maximum of 5 thumbprints are allowed.
139+
:Type: Array of Strings
140+
141+
Example::
142+
POST "<hostname>?Action=Action=UpdateOpenIDConnectProviderThumbprint
143+
&OpenIDConnectProviderArn=arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/quickstart
144+
&&ThumbprintList.list.1=ABCDB3515DD0D319DD219A43A9EA727AD6061234"

src/rgw/rgw_auth_s3.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ bool is_non_s3_op(RGWOpType op_type)
495495
case RGW_OP_DELETE_OIDC_PROVIDER:
496496
case RGW_OP_GET_OIDC_PROVIDER:
497497
case RGW_OP_LIST_OIDC_PROVIDERS:
498+
case RGW_OP_ADD_CLIENTID_TO_OIDC_PROVIDER:
499+
case RGW_OP_UPDATE_OIDC_PROVIDER_THUMBPRINT:
498500
case RGW_OP_PUBSUB_TOPIC_CREATE:
499501
case RGW_OP_PUBSUB_TOPICS_LIST:
500502
case RGW_OP_PUBSUB_TOPIC_GET:

src/rgw/rgw_iam_policy.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ static const actpair actpairs[] =
160160
{ "iam:DeleteOIDCProvider", iamDeleteOIDCProvider},
161161
{ "iam:GetOIDCProvider", iamGetOIDCProvider},
162162
{ "iam:ListOIDCProviders", iamListOIDCProviders},
163+
{ "iam:AddClientIdToOIDCProvider", iamAddClientIdToOIDCProvider},
164+
{ "iam:UpdateOIDCProviderThumbprint", iamUpdateOIDCProviderThumbprint},
163165
{ "iam:TagRole", iamTagRole},
164166
{ "iam:ListRoleTags", iamListRoleTags},
165167
{ "iam:UntagRole", iamUntagRole},
@@ -1550,6 +1552,12 @@ const char* action_bit_string(uint64_t action) {
15501552
case iamListOIDCProviders:
15511553
return "iam:ListOIDCProviders";
15521554

1555+
case iamAddClientIdToOIDCProvider:
1556+
return "iam:AddClientIdToOIDCProvider";
1557+
1558+
case iamUpdateOIDCProviderThumbprint:
1559+
return "iam:UpdateOIDCProviderThumbprint";
1560+
15531561
case iamTagRole:
15541562
return "iam:TagRole";
15551563

src/rgw/rgw_iam_policy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ enum {
143143
iamDeleteOIDCProvider,
144144
iamGetOIDCProvider,
145145
iamListOIDCProviders,
146+
iamAddClientIdToOIDCProvider,
147+
iamUpdateOIDCProviderThumbprint,
146148
iamTagRole,
147149
iamListRoleTags,
148150
iamUntagRole,

src/rgw/rgw_op_type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,7 @@ enum RGWOpType {
161161
RGW_OP_DELETE_OIDC_PROVIDER,
162162
RGW_OP_GET_OIDC_PROVIDER,
163163
RGW_OP_LIST_OIDC_PROVIDERS,
164+
RGW_OP_ADD_CLIENTID_TO_OIDC_PROVIDER,
165+
RGW_OP_UPDATE_OIDC_PROVIDER_THUMBPRINT,
164166
};
165167

src/rgw/rgw_rest_iam.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ static const std::unordered_map<std::string_view, op_generator> op_generators =
4545
{"ListOpenIDConnectProviders", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWListOIDCProviders;}},
4646
{"GetOpenIDConnectProvider", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWGetOIDCProvider;}},
4747
{"DeleteOpenIDConnectProvider", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWDeleteOIDCProvider;}},
48+
{"AddClientIDToOpenIDConnectProvider", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWAddClientIdToOIDCProvider;}},
49+
{"UpdateOpenIDConnectProviderThumbprint", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWUpdateOIDCProviderThumbprint;}},
4850
{"TagRole", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWTagRole(bl_post_body);}},
4951
{"ListRoleTags", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWListRoleTags;}},
5052
{"UntagRole", [](const bufferlist& bl_post_body) -> RGWOp* {return new RGWUntagRole(bl_post_body);}},

src/rgw/rgw_rest_oidc_provider.cc

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,147 @@ void RGWListOIDCProviders::execute(optional_yield y)
333333
s->formatter->close_section();
334334
}
335335
}
336+
337+
RGWAddClientIdToOIDCProvider::RGWAddClientIdToOIDCProvider()
338+
: RGWRestOIDCProvider(rgw::IAM::iamAddClientIdToOIDCProvider, RGW_CAP_WRITE)
339+
{
340+
}
341+
342+
int RGWAddClientIdToOIDCProvider::init_processing(optional_yield y)
343+
{
344+
std::string_view account;
345+
if (const auto& acc = s->auth.identity->get_account(); acc) {
346+
account = acc->id;
347+
} else {
348+
account = s->user->get_tenant();
349+
}
350+
std::string provider_arn = s->info.args.get("OpenIDConnectProviderArn");
351+
auto ret = validate_provider_arn(provider_arn, account,
352+
resource, url, s->err.message);
353+
if (ret < 0) {
354+
return ret;
355+
}
356+
357+
client_id = s->info.args.get("ClientID");
358+
359+
if (client_id.empty()) {
360+
s->err.message = "Missing required element ClientID";
361+
ldpp_dout(this, 20) << "ERROR: ClientID is empty" << dendl;
362+
return -EINVAL;
363+
}
364+
365+
if (client_id.size() > MAX_OIDC_CLIENT_ID_LEN) {
366+
s->err.message = "ClientID cannot exceed the maximum length of "
367+
+ std::to_string(MAX_OIDC_CLIENT_ID_LEN);
368+
ldpp_dout(this, 20) << "ERROR: ClientID length exceeded " << MAX_OIDC_CLIENT_ID_LEN << dendl;
369+
return -EINVAL;
370+
}
371+
372+
return 0;
373+
}
374+
375+
void RGWAddClientIdToOIDCProvider::execute(optional_yield y)
376+
{
377+
RGWOIDCProviderInfo info;
378+
op_ret = driver->load_oidc_provider(this, y, resource.account, url, info);
379+
380+
if (op_ret < 0) {
381+
if (op_ret != -ENOENT && op_ret != -EINVAL) {
382+
op_ret = ERR_INTERNAL_ERROR;
383+
}
384+
return;
385+
}
386+
387+
if(std::find(info.client_ids.begin(), info.client_ids.end(), client_id) != info.client_ids.end()) {
388+
op_ret = -EEXIST;
389+
} else {
390+
391+
info.client_ids.emplace_back(client_id);
392+
393+
constexpr bool exclusive = false;
394+
op_ret = driver->store_oidc_provider(this, y, info, exclusive);
395+
}
396+
if (op_ret == 0 || op_ret == -EEXIST) {
397+
op_ret = 0;
398+
s->formatter->open_object_section("AddClientIDToOpenIDConnectProviderResponse");
399+
s->formatter->open_object_section("ResponseMetadata");
400+
s->formatter->dump_string("RequestId", s->trans_id);
401+
s->formatter->close_section();
402+
s->formatter->open_object_section("AddClientIDToOpenIDConnectProviderResponse");
403+
dump_oidc_provider(info, s->formatter);
404+
s->formatter->close_section();
405+
s->formatter->close_section();
406+
}
407+
}
408+
409+
RGWUpdateOIDCProviderThumbprint::RGWUpdateOIDCProviderThumbprint()
410+
: RGWRestOIDCProvider(rgw::IAM::iamUpdateOIDCProviderThumbprint, RGW_CAP_WRITE)
411+
{
412+
}
413+
414+
int RGWUpdateOIDCProviderThumbprint::init_processing(optional_yield y)
415+
{
416+
std::string_view account;
417+
if (const auto& acc = s->auth.identity->get_account(); acc) {
418+
account = acc->id;
419+
} else {
420+
account = s->user->get_tenant();
421+
}
422+
std::string provider_arn = s->info.args.get("OpenIDConnectProviderArn");
423+
auto ret = validate_provider_arn(provider_arn, account,
424+
resource, url, s->err.message);
425+
if (ret < 0) {
426+
return ret;
427+
}
428+
429+
auto val_map = s->info.args.get_params();
430+
/* From AWS documentation here: https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateOpenIDConnectProviderThumbprint.html
431+
The list that you pass with this operation completely replaces the existing list of thumbprints. (The lists are not merged.) */
432+
for (auto& it : val_map) {
433+
if (it.first.find("ThumbprintList.member.") != string::npos) {
434+
if (it.second.size() > MAX_OIDC_THUMBPRINT_LEN) {
435+
s->err.message = "Thumbprint cannot exceed the maximum length of "
436+
+ std::to_string(MAX_OIDC_THUMBPRINT_LEN);
437+
ldpp_dout(this, 20) << "ERROR: Thumbprint exceeds maximum length of " << MAX_OIDC_THUMBPRINT_LEN << dendl;
438+
return -EINVAL;
439+
}
440+
thumbprints.emplace_back(it.second);
441+
}
442+
}
443+
444+
if (thumbprints.empty()) {
445+
s->err.message = "Missing required element ThumbprintList";
446+
ldpp_dout(this, 20) << "ERROR: Thumbprints list is empty" << dendl;
447+
return -EINVAL;
448+
}
449+
450+
return 0;
451+
}
452+
453+
void RGWUpdateOIDCProviderThumbprint::execute(optional_yield y)
454+
{
455+
RGWOIDCProviderInfo info;
456+
op_ret = driver->load_oidc_provider(this, y, resource.account, url, info);
457+
458+
if (op_ret < 0) {
459+
if (op_ret != -ENOENT && op_ret != -EINVAL) {
460+
op_ret = ERR_INTERNAL_ERROR;
461+
}
462+
return;
463+
}
464+
465+
info.thumbprints = std::move(thumbprints);
466+
467+
constexpr bool exclusive = false;
468+
op_ret = driver->store_oidc_provider(this, y, info, exclusive);
469+
if (op_ret == 0) {
470+
s->formatter->open_object_section("AddClientIDToOpenIDConnectProviderResponse");
471+
s->formatter->open_object_section("ResponseMetadata");
472+
s->formatter->dump_string("RequestId", s->trans_id);
473+
s->formatter->close_section();
474+
s->formatter->open_object_section("AddClientIDToOpenIDConnectProviderResponse");
475+
dump_oidc_provider(info, s->formatter);
476+
s->formatter->close_section();
477+
s->formatter->close_section();
478+
}
479+
}

src/rgw/rgw_rest_oidc_provider.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,27 @@ class RGWListOIDCProviders : public RGWRestOIDCProvider {
6262
const char* name() const override { return "list_oidc_providers"; }
6363
RGWOpType get_type() override { return RGW_OP_LIST_OIDC_PROVIDERS; }
6464
};
65+
66+
class RGWAddClientIdToOIDCProvider : public RGWRestOIDCProvider {
67+
std::string url;
68+
std::string client_id;
69+
public:
70+
RGWAddClientIdToOIDCProvider();
71+
72+
int init_processing(optional_yield y);
73+
void execute(optional_yield y) override;
74+
const char* name() const override { return "add_client_id_to_oidc_provider"; }
75+
RGWOpType get_type() override { return RGW_OP_ADD_CLIENTID_TO_OIDC_PROVIDER; }
76+
};
77+
78+
class RGWUpdateOIDCProviderThumbprint : public RGWRestOIDCProvider {
79+
std::string url;
80+
std::vector<std::string> thumbprints;
81+
public:
82+
RGWUpdateOIDCProviderThumbprint();
83+
84+
int init_processing(optional_yield y);
85+
void execute(optional_yield y) override;
86+
const char* name() const override { return "update_oidc_provider_thumbprint"; }
87+
RGWOpType get_type() override { return RGW_OP_UPDATE_OIDC_PROVIDER_THUMBPRINT; }
88+
};

src/rgw/rgw_rest_sts.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ WebTokenEngine::validate_signature(const DoutPrefixProvider* dpp, const jwt::dec
384384
found_valid_cert = true;
385385
break;
386386
}
387-
found_valid_cert = true;
388387
}
389388
if (! found_valid_cert) {
390389
ldpp_dout(dpp, 0) << "Cert doesn't match that with the thumbprints registered with oidc provider: " << cert.c_str() << dendl;

src/vstart.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1854,7 +1854,7 @@ do_rgw_create_users()
18541854
--access-key ABCDEFGHIJKLMNOPQRST \
18551855
--secret abcdefghijklmnopqrstuvwxyzabcdefghijklmn \
18561856
--display-name youruseridhere \
1857-
--email [email protected] --caps="roles=*;user-policy=*" -c $conf_fn > /dev/null
1857+
--email [email protected] --caps="roles=*;user-policy=*;oidc-provider=*" -c $conf_fn > /dev/null
18581858
$CEPH_BIN/radosgw-admin user create \
18591859
--uid 56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234 \
18601860
--access-key NOPQRSTUVWXYZABCDEFG \

0 commit comments

Comments
 (0)