mirror of
https://codeberg.org/pfzetto/axum-oidc
synced 2025-12-09 22:55:17 +01:00
fix: fixed redirect_uri with handler_uri in session
Previously the redirect_uri was the uri of the handler that needed authentication. Now one fixed redirect_uri for the entire application is used that will redirect the user to the correct handler after successful authentication. This commit should fix: #28, #27, #26, #21
This commit is contained in:
parent
58369449cf
commit
19adcbabd2
6 changed files with 246 additions and 239 deletions
124
src/builder.rs
124
src/builder.rs
|
|
@ -6,23 +6,22 @@ use openidconnect::{ClientId, ClientSecret, IssuerUrl};
|
|||
use crate::{error::Error, AdditionalClaims, Client, OidcClient, ProviderMetadata};
|
||||
|
||||
pub struct Unconfigured;
|
||||
pub struct ApplicationBaseUrl(Uri);
|
||||
pub struct OpenidconnectClient<AC: AdditionalClaims>(crate::Client<AC>);
|
||||
pub struct HttpClient(reqwest::Client);
|
||||
pub struct RedirectUrl(Uri);
|
||||
|
||||
pub struct ClientCredentials {
|
||||
id: Box<str>,
|
||||
secret: Option<Box<str>>,
|
||||
}
|
||||
|
||||
pub struct Builder<AC: AdditionalClaims, ApplicationBaseUrl, Credentials, Client, HttpClient> {
|
||||
application_base_url: ApplicationBaseUrl,
|
||||
pub struct Builder<AC: AdditionalClaims, Credentials, Client, HttpClient, RedirectUrl> {
|
||||
credentials: Credentials,
|
||||
client: Client,
|
||||
http_client: HttpClient,
|
||||
redirect_url: RedirectUrl,
|
||||
end_session_endpoint: Option<Uri>,
|
||||
scopes: Vec<Box<str>>,
|
||||
oidc_request_parameters: Vec<Box<str>>,
|
||||
auth_context_class: Option<Box<str>>,
|
||||
_ac: PhantomData<AC>,
|
||||
}
|
||||
|
|
@ -35,19 +34,13 @@ impl<AC: AdditionalClaims> Default for Builder<AC, (), (), (), ()> {
|
|||
impl<AC: AdditionalClaims> Builder<AC, (), (), (), ()> {
|
||||
/// create a new builder with default values
|
||||
pub fn new() -> Self {
|
||||
let oidc_request_parameters = ["code", "state", "session_state", "iss"]
|
||||
.into_iter()
|
||||
.map(Box::<str>::from)
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
application_base_url: (),
|
||||
credentials: (),
|
||||
client: (),
|
||||
http_client: (),
|
||||
redirect_url: (),
|
||||
end_session_endpoint: None,
|
||||
scopes: vec![Box::from("openid")],
|
||||
oidc_request_parameters,
|
||||
auth_context_class: None,
|
||||
_ac: PhantomData,
|
||||
}
|
||||
|
|
@ -61,7 +54,7 @@ impl<AC: AdditionalClaims> OidcClient<AC> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims, APPBASE, CREDS, CLIENT, HTTP> Builder<AC, APPBASE, CREDS, CLIENT, HTTP> {
|
||||
impl<AC: AdditionalClaims, CREDS, CLIENT, HTTP, RURL> Builder<AC, CREDS, CLIENT, HTTP, RURL> {
|
||||
/// add a scope to existing (default) scopes
|
||||
pub fn add_scope(mut self, scope: impl Into<Box<str>>) -> Self {
|
||||
self.scopes.push(scope.into());
|
||||
|
|
@ -73,28 +66,6 @@ impl<AC: AdditionalClaims, APPBASE, CREDS, CLIENT, HTTP> Builder<AC, APPBASE, CR
|
|||
self
|
||||
}
|
||||
|
||||
/// add a query parameter that will be filtered from requests to existing (default) filtered
|
||||
/// query parameters
|
||||
pub fn add_oidc_request_parameter(
|
||||
mut self,
|
||||
oidc_request_parameter: impl Into<Box<str>>,
|
||||
) -> Self {
|
||||
self.oidc_request_parameters
|
||||
.push(oidc_request_parameter.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// replace query parameters that will be filtered from requests (including default)
|
||||
pub fn with_oidc_request_parameters(
|
||||
mut self,
|
||||
oidc_request_parameters: impl Iterator<Item = impl Into<Box<str>>>,
|
||||
) -> Self {
|
||||
self.oidc_request_parameters = oidc_request_parameters
|
||||
.map(|x| x.into())
|
||||
.collect::<Vec<_>>();
|
||||
self
|
||||
}
|
||||
|
||||
/// authenticate with Authentication Context Class Reference
|
||||
pub fn with_auth_context_class(mut self, acr: impl Into<Box<str>>) -> Self {
|
||||
self.auth_context_class = Some(acr.into());
|
||||
|
|
@ -102,50 +73,29 @@ impl<AC: AdditionalClaims, APPBASE, CREDS, CLIENT, HTTP> Builder<AC, APPBASE, CR
|
|||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims, CREDS, CLIENT, HTTP> Builder<AC, (), CREDS, CLIENT, HTTP> {
|
||||
/// set application base url (e.g. https://example.com)
|
||||
pub fn with_application_base_url(
|
||||
self,
|
||||
url: impl Into<Uri>,
|
||||
) -> Builder<AC, ApplicationBaseUrl, CREDS, CLIENT, HTTP> {
|
||||
Builder {
|
||||
application_base_url: ApplicationBaseUrl(url.into()),
|
||||
credentials: self.credentials,
|
||||
client: self.client,
|
||||
http_client: self.http_client,
|
||||
end_session_endpoint: self.end_session_endpoint,
|
||||
scopes: self.scopes,
|
||||
oidc_request_parameters: self.oidc_request_parameters,
|
||||
auth_context_class: self.auth_context_class,
|
||||
_ac: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims, ABU, CLIENT, HTTP> Builder<AC, ABU, (), CLIENT, HTTP> {
|
||||
impl<AC: AdditionalClaims, CLIENT, HTTP, RURL> Builder<AC, (), CLIENT, HTTP, RURL> {
|
||||
/// set client id for authentication with issuer
|
||||
pub fn with_client_id(
|
||||
self,
|
||||
id: impl Into<Box<str>>,
|
||||
) -> Builder<AC, ABU, ClientCredentials, CLIENT, HTTP> {
|
||||
) -> Builder<AC, ClientCredentials, CLIENT, HTTP, RURL> {
|
||||
Builder::<_, _, _, _, _> {
|
||||
application_base_url: self.application_base_url,
|
||||
credentials: ClientCredentials {
|
||||
id: id.into(),
|
||||
secret: None,
|
||||
},
|
||||
client: self.client,
|
||||
http_client: self.http_client,
|
||||
redirect_url: self.redirect_url,
|
||||
end_session_endpoint: self.end_session_endpoint,
|
||||
scopes: self.scopes,
|
||||
oidc_request_parameters: self.oidc_request_parameters,
|
||||
auth_context_class: self.auth_context_class,
|
||||
_ac: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims, ABU, CLIENT, HTTP> Builder<AC, ABU, ClientCredentials, CLIENT, HTTP> {
|
||||
impl<AC: AdditionalClaims, CLIENT, HTTP, RURL> Builder<AC, ClientCredentials, CLIENT, HTTP, RURL> {
|
||||
/// set client secret for authentication with issuer
|
||||
pub fn with_client_secret(mut self, secret: impl Into<Box<str>>) -> Self {
|
||||
self.credentials.secret = Some(secret.into());
|
||||
|
|
@ -153,47 +103,65 @@ impl<AC: AdditionalClaims, ABU, CLIENT, HTTP> Builder<AC, ABU, ClientCredentials
|
|||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims, ABU, CREDS, CLIENT> Builder<AC, ABU, CREDS, CLIENT, ()> {
|
||||
impl<AC: AdditionalClaims, CREDS, CLIENT, RURL> Builder<AC, CREDS, CLIENT, (), RURL> {
|
||||
/// use custom http client
|
||||
pub fn with_http_client(
|
||||
self,
|
||||
client: reqwest::Client,
|
||||
) -> Builder<AC, ABU, CREDS, CLIENT, HttpClient> {
|
||||
) -> Builder<AC, CREDS, CLIENT, HttpClient, RURL> {
|
||||
Builder {
|
||||
application_base_url: self.application_base_url,
|
||||
credentials: self.credentials,
|
||||
client: self.client,
|
||||
http_client: HttpClient(client),
|
||||
redirect_url: self.redirect_url,
|
||||
end_session_endpoint: self.end_session_endpoint,
|
||||
scopes: self.scopes,
|
||||
oidc_request_parameters: self.oidc_request_parameters,
|
||||
auth_context_class: self.auth_context_class,
|
||||
_ac: self._ac,
|
||||
}
|
||||
}
|
||||
/// use default reqwest http client
|
||||
pub fn with_default_http_client(self) -> Builder<AC, ABU, CREDS, CLIENT, HttpClient> {
|
||||
pub fn with_default_http_client(self) -> Builder<AC, CREDS, CLIENT, HttpClient, RURL> {
|
||||
Builder {
|
||||
application_base_url: self.application_base_url,
|
||||
credentials: self.credentials,
|
||||
client: self.client,
|
||||
http_client: HttpClient(reqwest::Client::default()),
|
||||
redirect_url: self.redirect_url,
|
||||
end_session_endpoint: self.end_session_endpoint,
|
||||
scopes: self.scopes,
|
||||
oidc_request_parameters: self.oidc_request_parameters,
|
||||
auth_context_class: self.auth_context_class,
|
||||
_ac: self._ac,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims, ABU> Builder<AC, ABU, ClientCredentials, (), HttpClient> {
|
||||
impl<AC: AdditionalClaims, CREDS, CLIENT, HCLIENT> Builder<AC, CREDS, CLIENT, HCLIENT, ()> {
|
||||
pub fn with_redirect_url(
|
||||
self,
|
||||
redirect_url: Uri,
|
||||
) -> Builder<AC, CREDS, CLIENT, HCLIENT, RedirectUrl> {
|
||||
Builder {
|
||||
credentials: self.credentials,
|
||||
client: self.client,
|
||||
http_client: self.http_client,
|
||||
redirect_url: RedirectUrl(redirect_url),
|
||||
end_session_endpoint: self.end_session_endpoint,
|
||||
scopes: self.scopes,
|
||||
auth_context_class: self.auth_context_class,
|
||||
_ac: self._ac,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<AC: AdditionalClaims> Builder<AC, ClientCredentials, (), HttpClient, RedirectUrl> {
|
||||
/// provide issuer details manually
|
||||
pub fn manual(
|
||||
self,
|
||||
provider_metadata: ProviderMetadata,
|
||||
) -> Result<Builder<AC, ABU, ClientCredentials, OpenidconnectClient<AC>, HttpClient>, Error>
|
||||
{
|
||||
) -> Result<
|
||||
Builder<AC, ClientCredentials, OpenidconnectClient<AC>, HttpClient, RedirectUrl>,
|
||||
Error,
|
||||
> {
|
||||
let end_session_endpoint = provider_metadata
|
||||
.additional_metadata()
|
||||
.end_session_endpoint
|
||||
|
|
@ -208,16 +176,18 @@ impl<AC: AdditionalClaims, ABU> Builder<AC, ABU, ClientCredentials, (), HttpClie
|
|||
.secret
|
||||
.as_ref()
|
||||
.map(|x| ClientSecret::new(x.to_string())),
|
||||
);
|
||||
)
|
||||
.set_redirect_uri(openidconnect::RedirectUrl::new(
|
||||
self.redirect_url.0.to_string(),
|
||||
)?);
|
||||
|
||||
Ok(Builder {
|
||||
application_base_url: self.application_base_url,
|
||||
credentials: self.credentials,
|
||||
client: OpenidconnectClient(client),
|
||||
http_client: self.http_client,
|
||||
redirect_url: self.redirect_url,
|
||||
end_session_endpoint,
|
||||
scopes: self.scopes,
|
||||
oidc_request_parameters: self.oidc_request_parameters,
|
||||
auth_context_class: self.auth_context_class,
|
||||
_ac: self._ac,
|
||||
})
|
||||
|
|
@ -226,8 +196,10 @@ impl<AC: AdditionalClaims, ABU> Builder<AC, ABU, ClientCredentials, (), HttpClie
|
|||
pub async fn discover(
|
||||
self,
|
||||
issuer: impl Into<Uri>,
|
||||
) -> Result<Builder<AC, ABU, ClientCredentials, OpenidconnectClient<AC>, HttpClient>, Error>
|
||||
{
|
||||
) -> Result<
|
||||
Builder<AC, ClientCredentials, OpenidconnectClient<AC>, HttpClient, RedirectUrl>,
|
||||
Error,
|
||||
> {
|
||||
let issuer_url = IssuerUrl::new(issuer.into().to_string())?;
|
||||
let http_client = self.http_client.0.clone();
|
||||
let provider_metadata = ProviderMetadata::discover_async(issuer_url, &http_client);
|
||||
|
|
@ -237,17 +209,15 @@ impl<AC: AdditionalClaims, ABU> Builder<AC, ABU, ClientCredentials, (), HttpClie
|
|||
}
|
||||
|
||||
impl<AC: AdditionalClaims>
|
||||
Builder<AC, ApplicationBaseUrl, ClientCredentials, OpenidconnectClient<AC>, HttpClient>
|
||||
Builder<AC, ClientCredentials, OpenidconnectClient<AC>, HttpClient, RedirectUrl>
|
||||
{
|
||||
/// create oidc client
|
||||
pub fn build(self) -> OidcClient<AC> {
|
||||
OidcClient {
|
||||
scopes: self.scopes,
|
||||
oidc_request_parameters: self.oidc_request_parameters,
|
||||
client_id: self.credentials.id,
|
||||
client: self.client.0,
|
||||
http_client: self.http_client.0,
|
||||
application_base_url: self.application_base_url.0,
|
||||
end_session_endpoint: self.end_session_endpoint,
|
||||
auth_context_class: self.auth_context_class,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue