@@ -201,3 +201,40 @@ func (s *Server) HandleDeleteSession(w http.ResponseWriter, r *http.Request) {
201201 }
202202 w .WriteHeader (http .StatusNoContent )
203203}
204+
205+ // HandleSLO handles the SAML Single Logout endpoint. It invalidates the user's session
206+ // and returns a simple confirmation page.
207+ func (s * Server ) HandleSLO (w http.ResponseWriter , r * http.Request ) {
208+ if err := r .ParseForm (); err != nil {
209+ s .logger .Printf ("ERROR: Failed to parse form: %s" , err )
210+ http .Error (w , http .StatusText (http .StatusBadRequest ), http .StatusBadRequest )
211+ return
212+ }
213+
214+ // Check for session cookie
215+ sessionCookie , err := r .Cookie ("session" )
216+ if err == nil {
217+ // Delete the session
218+ if err := s .Store .Delete (fmt .Sprintf ("/sessions/%s" , sessionCookie .Value )); err != nil {
219+ if err != ErrNotFound {
220+ s .logger .Printf ("ERROR: Failed to delete session: %s" , err )
221+ http .Error (w , http .StatusText (http .StatusInternalServerError ), http .StatusInternalServerError )
222+ return
223+ }
224+ }
225+
226+ // Clear the session cookie
227+ http .SetCookie (w , & http.Cookie {
228+ Name : "session" ,
229+ Value : "" ,
230+ MaxAge : - 1 ,
231+ HttpOnly : true ,
232+ Secure : r .URL .Scheme == "https" ,
233+ Path : "/" ,
234+ })
235+ }
236+
237+ // Return a simple logout confirmation page
238+ w .Header ().Set ("Content-Type" , "text/html; charset=utf-8" )
239+ w .Write ([]byte ("<html><body><h1>Logout Successful</h1><p>You have been logged out.</p></body></html>" ))
240+ }
0 commit comments