Fix the issue when expired token did not forced reauthentication.

This commit is contained in:
2024-10-03 14:00:41 +01:00
parent 4968c5f93a
commit a4a943ae9c
3 changed files with 32 additions and 12 deletions
+13
View File
@@ -11,6 +11,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/gorilla/sessions"
) )
func generateNonce() (string, error) { func generateNonce() (string, error) {
@@ -82,6 +84,17 @@ func (t *TraefikOidc) handleLogout(rw http.ResponseWriter, req *http.Request) {
http.Error(rw, "Logged out", http.StatusForbidden) http.Error(rw, "Logged out", http.StatusForbidden)
} }
func (t *TraefikOidc) handleExpiredToken(rw http.ResponseWriter, req *http.Request, session *sessions.Session) {
// Clear the existing session
session.Options.MaxAge = -1
session.Values = make(map[interface{}]interface{})
err := session.Save(req, rw)
if err != nil {
t.logger.Errorf("Failed to clear session: %v", err)
}
t.initiateAuthentication(rw, req, session, t.redirectURL)
}
func (t *TraefikOidc) handleCallback(rw http.ResponseWriter, req *http.Request) (bool, string) { func (t *TraefikOidc) handleCallback(rw http.ResponseWriter, req *http.Request) (bool, string) {
ctx := req.Context() ctx := req.Context()
session, err := t.store.Get(req, cookieName) session, err := t.store.Get(req, cookieName)
+17 -11
View File
@@ -214,7 +214,7 @@ func (t *TraefikOidc) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if req.URL.Path == t.logoutURLPath { if req.URL.Path == t.logoutURLPath {
t.handleLogout(rw, req) t.handleLogout(rw, req)
return // Remove the http.Error call here return
} }
if t.redirectURL == "" { if t.redirectURL == "" {
@@ -240,13 +240,20 @@ func (t *TraefikOidc) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
return return
} }
if t.isUserAuthenticated(session) { authenticated, tokenExpired := t.isUserAuthenticated(session)
if authenticated {
t.logger.Debugf("User is authenticated, serving content") t.logger.Debugf("User is authenticated, serving content")
t.next.ServeHTTP(rw, req) t.next.ServeHTTP(rw, req)
return return
} }
// User is not authenticated or session has expired, start the auth process if tokenExpired {
t.logger.Debugf("Token has expired, initiating reauthentication")
t.handleExpiredToken(rw, req, session)
return
}
// User is not authenticated, start the auth process
t.initiateAuthentication(rw, req, session, t.redirectURL) t.initiateAuthentication(rw, req, session, t.redirectURL)
} }
@@ -270,35 +277,34 @@ func (t *TraefikOidc) determineHost(req *http.Request) string {
return req.Host return req.Host
} }
func (t *TraefikOidc) isUserAuthenticated(session *sessions.Session) bool { func (t *TraefikOidc) isUserAuthenticated(session *sessions.Session) (bool, bool) {
authenticated, _ := session.Values["authenticated"].(bool) authenticated, _ := session.Values["authenticated"].(bool)
if authenticated { if authenticated {
idToken, ok := session.Values["id_token"].(string) idToken, ok := session.Values["id_token"].(string)
if !ok || idToken == "" { if !ok || idToken == "" {
return false return false, false
} }
// Check if the token has expired
claims, err := extractClaims(idToken) claims, err := extractClaims(idToken)
if err != nil { if err != nil {
t.logger.Errorf("Failed to extract claims: %v", err) t.logger.Errorf("Failed to extract claims: %v", err)
return false return false, false
} }
exp, ok := claims["exp"].(float64) exp, ok := claims["exp"].(float64)
if !ok { if !ok {
t.logger.Errorf("Failed to get expiration time from claims") t.logger.Errorf("Failed to get expiration time from claims")
return false return false, false
} }
if time.Now().Unix() > int64(exp) { if time.Now().Unix() > int64(exp) {
t.logger.Debugf("Session has expired") t.logger.Debugf("Session has expired")
return false return false, true // Token expired
} }
return t.verifyToken(idToken) == nil return t.verifyToken(idToken) == nil, false
} }
return false return false, false
} }
func (t *TraefikOidc) initiateAuthentication(rw http.ResponseWriter, req *http.Request, session *sessions.Session, redirectURL string) { func (t *TraefikOidc) initiateAuthentication(rw http.ResponseWriter, req *http.Request, session *sessions.Session, redirectURL string) {
+2 -1
View File
@@ -375,8 +375,9 @@ func (suite *TraefikOidcTestSuite) TestIsUserAuthenticated() {
suite.mockTokenVerifier.On("VerifyToken", "valid.eyJleHAiOjk5OTk5OTk5OTl9.signature").Return(nil) suite.mockTokenVerifier.On("VerifyToken", "valid.eyJleHAiOjk5OTk5OTk5OTl9.signature").Return(nil)
authenticated := suite.oidc.isUserAuthenticated(session) authenticated, tokenExpired := suite.oidc.isUserAuthenticated(session)
suite.True(authenticated) suite.True(authenticated)
suite.False(tokenExpired)
} }
func (suite *TraefikOidcTestSuite) TestInitiateAuthentication() { func (suite *TraefikOidcTestSuite) TestInitiateAuthentication() {