1- use std:: {
2- future:: Future ,
3- hash:: { DefaultHasher , Hash , Hasher } ,
4- pin:: Pin ,
5- str:: FromStr ,
6- sync:: Arc ,
7- } ;
1+ use std:: { future:: Future , pin:: Pin , str:: FromStr , sync:: Arc } ;
82
93use crate :: { app_config:: AppConfig , AppState } ;
104use actix_web:: {
@@ -23,7 +17,6 @@ use openidconnect::{
2317 EndpointSet , IdTokenClaims , IssuerUrl , Nonce , OAuth2TokenResponse , RedirectUrl , Scope ,
2418 TokenResponse ,
2519} ;
26- use password_hash:: { rand_core:: OsRng , SaltString } ;
2720use serde:: { Deserialize , Serialize } ;
2821
2922use super :: http_client:: make_http_client;
@@ -83,10 +76,9 @@ fn get_app_host(config: &AppConfig) -> String {
8376 } ;
8477 log:: warn!(
8578 "No host or https_domain provided in the configuration, \
86- using \" {}\" as the app host to build the redirect URL. \
79+ using \" {host }\" as the app host to build the redirect URL. \
8780 This will only work locally. \
88- Disable this warning by providing a value for the \" host\" setting.",
89- host
81+ Disable this warning by providing a value for the \" host\" setting."
9082 ) ;
9183 host
9284}
@@ -125,11 +117,11 @@ async fn discover_provider_metadata(
125117 http_client : & AwcHttpClient ,
126118 issuer_url : IssuerUrl ,
127119) -> anyhow:: Result < openidconnect:: core:: CoreProviderMetadata > {
128- log:: debug!( "Discovering provider metadata for {}" , issuer_url ) ;
120+ log:: debug!( "Discovering provider metadata for {issuer_url}" ) ;
129121 let provider_metadata =
130122 openidconnect:: core:: CoreProviderMetadata :: discover_async ( issuer_url, http_client)
131123 . await
132- . with_context ( || format ! ( "Failed to discover OIDC provider metadata" ) ) ?;
124+ . with_context ( || "Failed to discover OIDC provider metadata" . to_string ( ) ) ?;
133125 log:: debug!( "Provider metadata discovered: {provider_metadata:?}" ) ;
134126 Ok ( provider_metadata)
135127}
@@ -192,19 +184,6 @@ impl<S> OidcService<S> {
192184 } )
193185 }
194186
195- fn build_auth_url ( & self , request : & ServiceRequest ) -> String {
196- let ( auth_url, csrf_token, nonce) = self
197- . oidc_client
198- . authorize_url (
199- CoreAuthenticationFlow :: AuthorizationCode ,
200- CsrfToken :: new_random,
201- Nonce :: new_random,
202- )
203- . add_scopes ( self . config . scopes . iter ( ) . cloned ( ) )
204- . url ( ) ;
205- auth_url. to_string ( )
206- }
207-
208187 fn handle_unauthenticated_request (
209188 & self ,
210189 request : ServiceRequest ,
@@ -271,7 +250,13 @@ where
271250 return self . handle_unauthenticated_request ( request) ;
272251 }
273252 Err ( e) => {
274- log:: error!( "An auth cookie is present but could not be verified: {e:?}" ) ;
253+ log:: debug!(
254+ "{:?}" ,
255+ e. context(
256+ "An auth cookie is present but could not be verified. \
257+ Redirecting to OIDC provider to re-authenticate."
258+ )
259+ ) ;
275260 return self . handle_unauthenticated_request ( request) ;
276261 }
277262 }
@@ -488,8 +473,7 @@ fn make_oidc_client(
488473 } ) ?;
489474 let needs_http = match redirect_url. url ( ) . host ( ) {
490475 Some ( openidconnect:: url:: Host :: Domain ( domain) ) => domain == "localhost" ,
491- Some ( openidconnect:: url:: Host :: Ipv4 ( _) ) => true ,
492- Some ( openidconnect:: url:: Host :: Ipv6 ( _) ) => true ,
476+ Some ( openidconnect:: url:: Host :: Ipv4 ( _) | openidconnect:: url:: Host :: Ipv6 ( _) ) => true ,
493477 None => false ,
494478 } ;
495479 if needs_http {
@@ -563,7 +547,7 @@ struct OidcLoginState {
563547fn hash_nonce ( nonce : & Nonce ) -> String {
564548 use argon2:: password_hash:: { rand_core:: OsRng , PasswordHasher , SaltString } ;
565549 let salt = SaltString :: generate ( & mut OsRng ) ;
566- // low-cost parameters: oidc tokens are short-lived
550+ // low-cost parameters: oidc tokens are short-lived and the source nonce is high-entropy
567551 let params = argon2:: Params :: new ( 8 , 1 , 1 , Some ( 16 ) ) . expect ( "bug: invalid Argon2 parameters" ) ;
568552 let argon2 = argon2:: Argon2 :: new ( argon2:: Algorithm :: Argon2id , argon2:: Version :: V0x13 , params) ;
569553 let hash = argon2
@@ -580,8 +564,12 @@ fn check_nonce(id_token_nonce: Option<&Nonce>, state_nonce: &Nonce) -> Result<()
580564}
581565
582566fn nonce_matches ( id_token_nonce : & Nonce , state_nonce : & Nonce ) -> Result < ( ) , String > {
583- log:: debug!( "Checking nonce: {} == {}" , id_token_nonce. secret( ) , state_nonce. secret( ) ) ;
584- let hash = argon2:: password_hash:: PasswordHash :: new ( & id_token_nonce. secret ( ) ) . map_err ( |e| {
567+ log:: debug!(
568+ "Checking nonce: {} == {}" ,
569+ id_token_nonce. secret( ) ,
570+ state_nonce. secret( )
571+ ) ;
572+ let hash = argon2:: password_hash:: PasswordHash :: new ( id_token_nonce. secret ( ) ) . map_err ( |e| {
585573 format ! (
586574 "Failed to parse state nonce ({}): {e}" ,
587575 id_token_nonce. secret( )
@@ -623,5 +611,5 @@ fn get_state_from_cookie(request: &ServiceRequest) -> anyhow::Result<OidcLoginSt
623611 format ! ( "No {SQLPAGE_STATE_COOKIE_NAME} cookie found for {SQLPAGE_REDIRECT_URI}" )
624612 } ) ?;
625613 serde_json:: from_str ( state_cookie. value ( ) )
626- . with_context ( || format ! ( "Failed to parse OIDC state from cookie" ) )
614+ . with_context ( || format ! ( "Failed to parse OIDC state from cookie: {state_cookie} " ) )
627615}
0 commit comments