Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/methods/shield-oidc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod builders;
mod claims;
mod client;
mod connection;
mod metadata;
mod method;
mod provider;
mod session;
Expand Down
34 changes: 34 additions & 0 deletions packages/methods/shield-oidc/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use openidconnect::{
AdditionalProviderMetadata, IntrospectionUrl, ProviderMetadata, RevocationUrl,
core::{
CoreAuthDisplay, CoreClaimName, CoreClaimType, CoreClientAuthMethod, CoreGrantType,
CoreJsonWebKey, CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm,
CoreResponseMode, CoreResponseType, CoreSubjectIdentifierType,
},
};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct NonStandardProviderMetadata {
#[serde(default)]
pub introspection_endpoint: Option<IntrospectionUrl>,
#[serde(default)]
pub revocation_endpoint: Option<RevocationUrl>,
}

impl AdditionalProviderMetadata for NonStandardProviderMetadata {}

pub type OidcProviderMetadata = ProviderMetadata<
NonStandardProviderMetadata,
CoreAuthDisplay,
CoreClientAuthMethod,
CoreClaimName,
CoreClaimType,
CoreGrantType,
CoreJweContentEncryptionAlgorithm,
CoreJweKeyManagementAlgorithm,
CoreJsonWebKey,
CoreResponseMode,
CoreResponseType,
CoreSubjectIdentifierType,
>;
3 changes: 1 addition & 2 deletions packages/methods/shield-oidc/src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,7 @@ impl<U: User> Method for OidcMethod<U> {
_session: Session,
options: &ShieldOptions,
) -> Result<Response, ShieldError> {
// TODO: Revocation URL is always `EndpointNotSet` when using `from_provider_metadata`,
// because `ProviderMetadata` does not support `introspection_endpoint` and `revocation_endpoint`.
// TODO: See [`OidcProvider::oidc_client`].

// let provider = match request.provider_id {
// Some(provider_id) => self.oidc_provider_by_id_or_slug(&provider_id).await?,
Expand Down
54 changes: 43 additions & 11 deletions packages/methods/shield-oidc/src/provider.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
use bon::Builder;
use openidconnect::{
AuthUrl, Client, ClientId, ClientSecret, EmptyAdditionalClaims,
EmptyAdditionalProviderMetadata, EndpointMaybeSet, EndpointNotSet, EndpointSet, IssuerUrl,
JsonWebKeySet, JsonWebKeySetUrl, ProviderMetadata, RedirectUrl, StandardErrorResponse,
TokenUrl, UserInfoUrl,
AuthUrl, Client, ClientId, ClientSecret, EmptyAdditionalClaims, EndpointMaybeSet,
EndpointNotSet, EndpointSet, IntrospectionUrl, IssuerUrl, JsonWebKeySet, JsonWebKeySetUrl,
RedirectUrl, RevocationUrl, StandardErrorResponse, TokenUrl, UserInfoUrl,
core::{
CoreAuthDisplay, CoreAuthPrompt, CoreClient, CoreErrorResponseType, CoreGenderClaim,
CoreJsonWebKey, CoreJweContentEncryptionAlgorithm, CoreJwsSigningAlgorithm,
CoreProviderMetadata, CoreRevocableToken, CoreRevocationErrorResponse,
CoreTokenIntrospectionResponse, CoreTokenResponse,
CoreRevocableToken, CoreRevocationErrorResponse, CoreTokenIntrospectionResponse,
CoreTokenResponse,
},
};
use shield::{ConfigurationError, Provider};

use crate::{client::async_http_client, method::OIDC_METHOD_ID};
use crate::{
client::async_http_client,
metadata::{NonStandardProviderMetadata, OidcProviderMetadata},
method::OIDC_METHOD_ID,
};

type OidcClient = Client<
EmptyAdditionalClaims,
Expand Down Expand Up @@ -83,7 +86,7 @@ impl OidcProvider {
let async_http_client = async_http_client()?;

let provider_metadata = if let Some(discovery_url) = &self.discovery_url {
CoreProviderMetadata::discover_async(
OidcProviderMetadata::discover_async(
// TODO: Consider stripping `/.well-known/openid-configuration` so `openidconnect` doesn't error.
IssuerUrl::new(discovery_url.clone())
.map_err(|err| ConfigurationError::Invalid(err.to_string()))?,
Expand All @@ -92,7 +95,7 @@ impl OidcProvider {
.await
.map_err(|err| ConfigurationError::Invalid(err.to_string()))?
} else {
let mut provider_metadata = ProviderMetadata::new(
let mut provider_metadata = OidcProviderMetadata::new(
IssuerUrl::new(
self.issuer_url
.clone()
Expand Down Expand Up @@ -128,7 +131,24 @@ impl OidcProvider {
CoreJwsSigningAlgorithm::EdDsa,
CoreJwsSigningAlgorithm::None,
],
EmptyAdditionalProviderMetadata {},
NonStandardProviderMetadata {
introspection_endpoint: self
.introspection_url
.as_ref()
.map(|introspection_url| {
IntrospectionUrl::new(introspection_url.clone())
.map_err(|err| ConfigurationError::Invalid(err.to_string()))
})
.transpose()?,
revocation_endpoint: self
.revocation_url
.as_ref()
.map(|revocation_url| {
RevocationUrl::new(revocation_url.clone())
.map_err(|err| ConfigurationError::Invalid(err.to_string()))
})
.transpose()?,
},
);

provider_metadata = provider_metadata.set_jwks(
Expand Down Expand Up @@ -160,14 +180,26 @@ impl OidcProvider {
self.client_secret.clone().map(ClientSecret::new),
);

// TODO: Upstream: _option version of these (and other) functions which set the type to EndpointMaybeSet.

// if let Some(introspection_endpoint) = provider_metadata
// .additional_metadata()
// .introspection_endpoint
// {
// client = client.set_introspection_url(introspection_endpoint);
// }
// if let Some(revocation_url) = provider_metadata.additional_metadata().revocation_endpoint {
// client = client.set_introspection_url(revocation_url);
// }

if let Some(redirect_url) = &self.redirect_url {
client = client.set_redirect_uri(
RedirectUrl::new(redirect_url.clone())
.map_err(|err| ConfigurationError::Invalid(err.to_string()))?,
);
}

// TODO: Common client options.
// TODO: Client options.

Ok(client)
}
Expand Down