Skip to content

Commit f884521

Browse files
feat(shield-oidc): add additional provider metadata (#116)
1 parent b377076 commit f884521

4 files changed

Lines changed: 79 additions & 13 deletions

File tree

packages/methods/shield-oidc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod builders;
22
mod claims;
33
mod client;
44
mod connection;
5+
mod metadata;
56
mod method;
67
mod provider;
78
mod session;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use openidconnect::{
2+
AdditionalProviderMetadata, IntrospectionUrl, ProviderMetadata, RevocationUrl,
3+
core::{
4+
CoreAuthDisplay, CoreClaimName, CoreClaimType, CoreClientAuthMethod, CoreGrantType,
5+
CoreJsonWebKey, CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm,
6+
CoreResponseMode, CoreResponseType, CoreSubjectIdentifierType,
7+
},
8+
};
9+
use serde::{Deserialize, Serialize};
10+
11+
#[derive(Clone, Debug, Deserialize, Serialize)]
12+
pub struct NonStandardProviderMetadata {
13+
#[serde(default)]
14+
pub introspection_endpoint: Option<IntrospectionUrl>,
15+
#[serde(default)]
16+
pub revocation_endpoint: Option<RevocationUrl>,
17+
}
18+
19+
impl AdditionalProviderMetadata for NonStandardProviderMetadata {}
20+
21+
pub type OidcProviderMetadata = ProviderMetadata<
22+
NonStandardProviderMetadata,
23+
CoreAuthDisplay,
24+
CoreClientAuthMethod,
25+
CoreClaimName,
26+
CoreClaimType,
27+
CoreGrantType,
28+
CoreJweContentEncryptionAlgorithm,
29+
CoreJweKeyManagementAlgorithm,
30+
CoreJsonWebKey,
31+
CoreResponseMode,
32+
CoreResponseType,
33+
CoreSubjectIdentifierType,
34+
>;

packages/methods/shield-oidc/src/method.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,7 @@ impl<U: User> Method for OidcMethod<U> {
425425
_session: Session,
426426
options: &ShieldOptions,
427427
) -> Result<Response, ShieldError> {
428-
// TODO: Revocation URL is always `EndpointNotSet` when using `from_provider_metadata`,
429-
// because `ProviderMetadata` does not support `introspection_endpoint` and `revocation_endpoint`.
428+
// TODO: See [`OidcProvider::oidc_client`].
430429

431430
// let provider = match request.provider_id {
432431
// Some(provider_id) => self.oidc_provider_by_id_or_slug(&provider_id).await?,

packages/methods/shield-oidc/src/provider.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
use bon::Builder;
22
use openidconnect::{
3-
AuthUrl, Client, ClientId, ClientSecret, EmptyAdditionalClaims,
4-
EmptyAdditionalProviderMetadata, EndpointMaybeSet, EndpointNotSet, EndpointSet, IssuerUrl,
5-
JsonWebKeySet, JsonWebKeySetUrl, ProviderMetadata, RedirectUrl, StandardErrorResponse,
6-
TokenUrl, UserInfoUrl,
3+
AuthUrl, Client, ClientId, ClientSecret, EmptyAdditionalClaims, EndpointMaybeSet,
4+
EndpointNotSet, EndpointSet, IntrospectionUrl, IssuerUrl, JsonWebKeySet, JsonWebKeySetUrl,
5+
RedirectUrl, RevocationUrl, StandardErrorResponse, TokenUrl, UserInfoUrl,
76
core::{
87
CoreAuthDisplay, CoreAuthPrompt, CoreClient, CoreErrorResponseType, CoreGenderClaim,
98
CoreJsonWebKey, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm,
10-
CoreProviderMetadata, CoreRevocableToken, CoreRevocationErrorResponse,
11-
CoreTokenIntrospectionResponse, CoreTokenResponse,
9+
CoreRevocableToken, CoreRevocationErrorResponse, CoreTokenIntrospectionResponse,
10+
CoreTokenResponse,
1211
},
1312
};
1413
use shield::{ConfigurationError, Provider};
1514

16-
use crate::{client::async_http_client, method::OIDC_METHOD_ID};
15+
use crate::{
16+
client::async_http_client,
17+
metadata::{NonStandardProviderMetadata, OidcProviderMetadata},
18+
method::OIDC_METHOD_ID,
19+
};
1720

1821
type OidcClient = Client<
1922
EmptyAdditionalClaims,
@@ -83,7 +86,7 @@ impl OidcProvider {
8386
let async_http_client = async_http_client()?;
8487

8588
let provider_metadata = if let Some(discovery_url) = &self.discovery_url {
86-
CoreProviderMetadata::discover_async(
89+
OidcProviderMetadata::discover_async(
8790
// TODO: Consider stripping `/.well-known/openid-configuration` so `openidconnect` doesn't error.
8891
IssuerUrl::new(discovery_url.clone())
8992
.map_err(|err| ConfigurationError::Invalid(err.to_string()))?,
@@ -92,7 +95,7 @@ impl OidcProvider {
9295
.await
9396
.map_err(|err| ConfigurationError::Invalid(err.to_string()))?
9497
} else {
95-
let mut provider_metadata = ProviderMetadata::new(
98+
let mut provider_metadata = OidcProviderMetadata::new(
9699
IssuerUrl::new(
97100
self.issuer_url
98101
.clone()
@@ -128,7 +131,24 @@ impl OidcProvider {
128131
CoreJwsSigningAlgorithm::EdDsa,
129132
CoreJwsSigningAlgorithm::None,
130133
],
131-
EmptyAdditionalProviderMetadata {},
134+
NonStandardProviderMetadata {
135+
introspection_endpoint: self
136+
.introspection_url
137+
.as_ref()
138+
.map(|introspection_url| {
139+
IntrospectionUrl::new(introspection_url.clone())
140+
.map_err(|err| ConfigurationError::Invalid(err.to_string()))
141+
})
142+
.transpose()?,
143+
revocation_endpoint: self
144+
.revocation_url
145+
.as_ref()
146+
.map(|revocation_url| {
147+
RevocationUrl::new(revocation_url.clone())
148+
.map_err(|err| ConfigurationError::Invalid(err.to_string()))
149+
})
150+
.transpose()?,
151+
},
132152
);
133153

134154
provider_metadata = provider_metadata.set_jwks(
@@ -160,14 +180,26 @@ impl OidcProvider {
160180
self.client_secret.clone().map(ClientSecret::new),
161181
);
162182

183+
// TODO: Upstream: _option version of these (and other) functions which set the type to EndpointMaybeSet.
184+
185+
// if let Some(introspection_endpoint) = provider_metadata
186+
// .additional_metadata()
187+
// .introspection_endpoint
188+
// {
189+
// client = client.set_introspection_url(introspection_endpoint);
190+
// }
191+
// if let Some(revocation_url) = provider_metadata.additional_metadata().revocation_endpoint {
192+
// client = client.set_introspection_url(revocation_url);
193+
// }
194+
163195
if let Some(redirect_url) = &self.redirect_url {
164196
client = client.set_redirect_uri(
165197
RedirectUrl::new(redirect_url.clone())
166198
.map_err(|err| ConfigurationError::Invalid(err.to_string()))?,
167199
);
168200
}
169201

170-
// TODO: Common client options.
202+
// TODO: Client options.
171203

172204
Ok(client)
173205
}

0 commit comments

Comments
 (0)