@@ -19,16 +19,16 @@ import (
1919 "github.com/pborman/uuid"
2020 "github.com/pkg/errors"
2121 "github.com/sirupsen/logrus"
22+ "go.opentelemetry.io/otel/attribute"
2223 "go.opentelemetry.io/otel/trace"
2324
24- "github.com/ory/hydra/v2/flow"
25- "github.com/ory/hydra/v2/oauth2/flowctx"
26-
2725 "github.com/ory/fosite"
2826 "github.com/ory/fosite/handler/openid"
2927 "github.com/ory/fosite/token/jwt"
3028 "github.com/ory/hydra/v2/client"
3129 "github.com/ory/hydra/v2/driver/config"
30+ "github.com/ory/hydra/v2/flow"
31+ "github.com/ory/hydra/v2/oauth2/flowctx"
3232 "github.com/ory/hydra/v2/x"
3333 "github.com/ory/x/errorsx"
3434 "github.com/ory/x/mapx"
@@ -705,35 +705,33 @@ func (s *DefaultStrategy) verifyConsent(ctx context.Context, _ http.ResponseWrit
705705 return session , f , nil
706706}
707707
708- func (s * DefaultStrategy ) generateFrontChannelLogoutURLs (ctx context.Context , subject , sid string ) ([]string , error ) {
709- clients , err := s .r .ConsentManager ().ListUserAuthenticatedClientsWithFrontChannelLogout (ctx , subject , sid )
710- if err != nil {
711- return nil , err
712- }
713-
714- var urls []string
708+ func generateFrontChannelLogoutURLs (clients []client.Client , iss , sid string ) (urls []string , _ error ) {
715709 for _ , c := range clients {
716710 u , err := url .Parse (c .FrontChannelLogoutURI )
717711 if err != nil {
718712 return nil , errorsx .WithStack (fosite .ErrServerError .WithHintf ("Unable to parse frontchannel_logout_uri because %s." , c .FrontChannelLogoutURI ).WithDebug (err .Error ()))
719713 }
720714
721715 urls = append (urls , urlx .SetQuery (u , url.Values {
722- "iss" : {s . c . IssuerURL ( ctx ). String () },
716+ "iss" : {iss },
723717 "sid" : {sid },
724718 }).String ())
725719 }
726720
727721 return urls , nil
728722}
729723
730- func (s * DefaultStrategy ) executeBackChannelLogout (r * http.Request , subject , sid string ) error {
731- ctx := r .Context ()
732- clients , err := s .r .ConsentManager ().ListUserAuthenticatedClientsWithBackChannelLogout (ctx , subject , sid )
733- if err != nil {
734- return err
724+ func (s * DefaultStrategy ) executeBackChannelLogout (ctx context.Context , clients []client.Client , sid string ) (err error ) {
725+ if len (clients ) == 0 {
726+ return nil
735727 }
736728
729+ ctx , span := trace .SpanFromContext (ctx ).TracerProvider ().Tracer ("" ).Start (ctx , "DefaultStrategy.executeBackChannelLogout" ,
730+ trace .WithAttributes (
731+ attribute .Int ("clients" , len (clients )),
732+ attribute .String ("sid" , sid )))
733+ defer otelx .End (span , & err )
734+
737735 openIDKeyID , err := s .r .OpenIDJWTStrategy ().GetPublicKeyID (ctx )
738736 if err != nil {
739737 return err
@@ -771,15 +769,19 @@ func (s *DefaultStrategy) executeBackChannelLogout(r *http.Request, subject, sid
771769 tasks = append (tasks , task {url : c .BackChannelLogoutURI , clientID : c .GetID (), token : t })
772770 }
773771
774- span := trace .SpanFromContext (ctx )
775772 cl := s .r .HTTPClient (ctx )
776- execute := func (t task ) {
777- log := s .r .Logger ().WithRequest (r ).
773+ cl .HTTPClient .CheckRedirect = func (req * http.Request , via []* http.Request ) error {
774+ return http .ErrUseLastResponse
775+ }
776+ execute := func (ctx context.Context , t task ) {
777+ log := s .r .Logger ().
778778 WithField ("client_id" , t .clientID ).
779779 WithField ("backchannel_logout_url" , t .url )
780780
781781 body := url.Values {"logout_token" : {t .token }}.Encode ()
782- req , err := retryablehttp .NewRequestWithContext (trace .ContextWithSpan (context .Background (), span ), "POST" , t .url , []byte (body ))
782+ ctx , cancel := context .WithTimeout (ctx , 30 * time .Second )
783+ defer cancel ()
784+ req , err := retryablehttp .NewRequestWithContext (ctx , "POST" , t .url , []byte (body ))
783785 if err != nil {
784786 log .WithError (err ).Error ("Unable to construct OpenID Connect Back-Channel Logout Request" )
785787 return
@@ -803,7 +805,7 @@ func (s *DefaultStrategy) executeBackChannelLogout(r *http.Request, subject, sid
803805 }
804806
805807 for _ , t := range tasks {
806- go execute (t )
808+ go execute (context . WithoutCancel ( ctx ), t )
807809 }
808810
809811 return nil
@@ -999,9 +1001,8 @@ func (s *DefaultStrategy) issueLogoutVerifier(ctx context.Context, w http.Respon
9991001 return nil , errorsx .WithStack (ErrAbortOAuth2Request )
10001002}
10011003
1002- func (s * DefaultStrategy ) performBackChannelLogoutAndDeleteSession (r * http.Request , subject string , sid string ) error {
1003- ctx := r .Context ()
1004- if err := s .executeBackChannelLogout (r , subject , sid ); err != nil {
1004+ func (s * DefaultStrategy ) performBackChannelLogoutAndDeleteSession (ctx context.Context , clients []client.Client , sid string ) error {
1005+ if err := s .executeBackChannelLogout (ctx , clients , sid ); err != nil {
10051006 return err
10061007 }
10071008
@@ -1028,7 +1029,7 @@ func (s *DefaultStrategy) performBackChannelLogoutAndDeleteSession(r *http.Reque
10281029func (s * DefaultStrategy ) completeLogout (ctx context.Context , w http.ResponseWriter , r * http.Request ) (* flow.LogoutResult , error ) {
10291030 verifier := r .URL .Query ().Get ("logout_verifier" )
10301031
1031- lr , err := s .r .ConsentManager ().VerifyAndInvalidateLogoutRequest (r . Context () , verifier )
1032+ lr , err := s .r .ConsentManager ().VerifyAndInvalidateLogoutRequest (ctx , verifier )
10321033 if err != nil {
10331034 return nil , err
10341035 }
@@ -1069,12 +1070,17 @@ func (s *DefaultStrategy) completeLogout(ctx context.Context, w http.ResponseWri
10691070
10701071 _ , _ = s .revokeAuthenticationCookie (w , r , store ) // Cookie removal is optional
10711072
1072- urls , err := s .generateFrontChannelLogoutURLs (r .Context (), lr .Subject , lr .SessionID )
1073+ frontChannelClients , backChannelClients , err := s .r .ConsentManager ().ListClientsWithLogoutURLsForSubjectAndSID (ctx , lr .Subject , lr .SessionID )
1074+ if err != nil {
1075+ return nil , err
1076+ }
1077+
1078+ urls , err := generateFrontChannelLogoutURLs (frontChannelClients , s .c .IssuerURL (ctx ).String (), lr .SessionID )
10731079 if err != nil {
10741080 return nil , err
10751081 }
10761082
1077- if err := s .performBackChannelLogoutAndDeleteSession (r , lr . Subject , lr .SessionID ); err != nil {
1083+ if err := s .performBackChannelLogoutAndDeleteSession (ctx , backChannelClients , lr .SessionID ); err != nil {
10781084 return nil , err
10791085 }
10801086
@@ -1110,7 +1116,12 @@ func (s *DefaultStrategy) HandleHeadlessLogout(ctx context.Context, _ http.Respo
11101116 return lsErr
11111117 }
11121118
1113- if err := s .performBackChannelLogoutAndDeleteSession (r , loginSession .Subject , sid ); err != nil {
1119+ _ , clients , err := s .r .ConsentManager ().ListClientsWithLogoutURLsForSubjectAndSID (ctx , loginSession .Subject , sid )
1120+ if err != nil {
1121+ return err
1122+ }
1123+
1124+ if err := s .performBackChannelLogoutAndDeleteSession (ctx , clients , sid ); err != nil {
11141125 return err
11151126 }
11161127
0 commit comments