Added first implementation of RP Initiated Logout

Created a new extractor for RP-Initiated-Logout and modified example to
use it.
This commit is contained in:
Paul Zinselmeyer 2024-03-25 17:20:44 +01:00
parent a522b7936d
commit 1844b880c1
Signed by: pfzetto
GPG key ID: B471A1AF06C895FD
8 changed files with 171 additions and 17 deletions

View file

@ -6,10 +6,12 @@ use crate::error::Error;
use http::Uri;
use openidconnect::{
core::{
CoreAuthDisplay, CoreAuthPrompt, CoreErrorResponseType, CoreGenderClaim, CoreJsonWebKey,
CoreJsonWebKeyType, CoreJsonWebKeyUse, CoreJweContentEncryptionAlgorithm,
CoreJwsSigningAlgorithm, CoreProviderMetadata, CoreRevocableToken,
CoreRevocationErrorResponse, CoreTokenIntrospectionResponse, CoreTokenType,
CoreAuthDisplay, CoreAuthPrompt, CoreClaimName, CoreClaimType, CoreClientAuthMethod,
CoreErrorResponseType, CoreGenderClaim, CoreGrantType, CoreJsonWebKey, CoreJsonWebKeyType,
CoreJsonWebKeyUse, CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm,
CoreJwsSigningAlgorithm, CoreProviderMetadata, CoreResponseMode, CoreResponseType,
CoreRevocableToken, CoreRevocationErrorResponse, CoreSubjectIdentifierType,
CoreTokenIntrospectionResponse, CoreTokenType,
},
reqwest::async_http_client,
ClientId, ClientSecret, CsrfToken, EmptyExtraTokenFields, IdTokenFields, IssuerUrl, Nonce,
@ -21,7 +23,7 @@ pub mod error;
mod extractor;
mod middleware;
pub use extractor::{OidcAccessToken, OidcClaims};
pub use extractor::{OidcAccessToken, OidcClaims, OidcRpInitiatedLogout};
pub use middleware::{OidcAuthLayer, OidcAuthMiddleware, OidcLoginLayer, OidcLoginMiddleware};
const SESSION_KEY: &str = "axum-oidc";
@ -66,14 +68,34 @@ type Client<AC> = openidconnect::Client<
CoreRevocationErrorResponse,
>;
type ProviderMetadata = openidconnect::ProviderMetadata<
AdditionalProviderMetadata,
CoreAuthDisplay,
CoreClientAuthMethod,
CoreClaimName,
CoreClaimType,
CoreGrantType,
CoreJweContentEncryptionAlgorithm,
CoreJweKeyManagementAlgorithm,
CoreJwsSigningAlgorithm,
CoreJsonWebKeyType,
CoreJsonWebKeyUse,
CoreJsonWebKey,
CoreResponseMode,
CoreResponseType,
CoreSubjectIdentifierType,
>;
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
/// OpenID Connect Client
#[derive(Clone)]
pub struct OidcClient<AC: AdditionalClaims> {
scopes: Vec<String>,
client_id: String,
client: Client<AC>,
application_base_url: Uri,
end_session_endpoint: Option<Uri>,
}
impl<AC: AdditionalClaims> OidcClient<AC> {
@ -85,17 +107,25 @@ impl<AC: AdditionalClaims> OidcClient<AC> {
scopes: Vec<String>,
) -> Result<Self, Error> {
let provider_metadata =
CoreProviderMetadata::discover_async(IssuerUrl::new(issuer)?, async_http_client)
.await?;
ProviderMetadata::discover_async(IssuerUrl::new(issuer)?, async_http_client).await?;
let end_session_endpoint = provider_metadata
.additional_metadata()
.end_session_endpoint
.clone()
.map(Uri::from_maybe_shared)
.transpose()
.map_err(Error::InvalidEndSessionEndpoint)?;
let client = Client::from_provider_metadata(
provider_metadata,
ClientId::new(client_id),
ClientId::new(client_id.clone()),
client_secret.map(ClientSecret::new),
);
Ok(Self {
scopes,
client,
client_id,
application_base_url,
end_session_endpoint,
})
}
}
@ -138,3 +168,9 @@ impl OidcSession {
.map(|x| RefreshToken::new(x.to_string()))
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct AdditionalProviderMetadata {
end_session_endpoint: Option<String>,
}
impl openidconnect::AdditionalProviderMetadata for AdditionalProviderMetadata {}