@@ -32,7 +32,7 @@ use oauth2::{
3232 RedirectUrl , Scope , TokenResponse ,
3333} ;
3434use openidconnect:: core:: { CoreAuthenticationFlow , CoreClient , CoreProviderMetadata } ;
35- use openidconnect:: { AccessTokenHash , ClientId , IssuerUrl , Nonce } ;
35+ use openidconnect:: { AccessTokenHash , ClientId , IssuerUrl , Nonce , ProviderMetadataWithLogout } ;
3636use redis:: AsyncCommands ;
3737use serde:: { Deserialize , Serialize } ;
3838use serde_json:: json;
@@ -276,9 +276,35 @@ pub async fn logout(
276276 "Client ID for OpenID provider must be set"
277277 )
278278 . to_string ( ) ;
279+
280+ let metadata = ProviderMetadataWithLogout :: discover_async (
281+ IssuerUrl :: new ( issuer_url. clone ( ) ) . expect ( "IssuerUrl for OpenID provider must be set" ) ,
282+ async_http_client,
283+ )
284+ . await
285+ . map_err ( |err| format ! ( "Failed to discover OIDC provider {:?}" , err) )
286+ . unwrap ( ) ;
287+
288+ let end_session_endpoint = metadata. additional_metadata ( ) . end_session_endpoint . clone ( ) ;
289+
290+ let post_logout_redirect_uri = match end_session_endpoint {
291+ Some ( url) => url. to_string ( ) ,
292+ None => format ! (
293+ "{}/protocol/openid-connect/logout?post_logout_redirect_uri={}&client_id={}" ,
294+ issuer_url,
295+ data. redirect_uri. clone( ) . unwrap_or(
296+ req. headers( )
297+ . get( "Referer" )
298+ . map_or( "/" , |h| h. to_str( ) . unwrap_or( "/" ) )
299+ . to_string( )
300+ ) ,
301+ client_id
302+ ) ,
303+ } ;
304+
279305 let logout_url = format ! (
280- "{}/protocol/openid-connect/logout ?post_logout_redirect_uri={}&client_id={}" ,
281- issuer_url ,
306+ "{}?post_logout_redirect_uri={}&client_id={}" ,
307+ post_logout_redirect_uri ,
282308 data. redirect_uri. clone( ) . unwrap_or(
283309 req. headers( )
284310 . get( "Referer" )
0 commit comments