mirror of
https://github.com/nais/wonderwall.git
synced 2026-05-20 23:32:57 +00:00
feat: implement self-initiated logout
Co-authored-by: Kent Daleng <kent.daleng@nav.no>
This commit is contained in:
@@ -16,26 +16,28 @@ type Config struct {
|
||||
}
|
||||
|
||||
type IDPorten struct {
|
||||
ClientID string `json:"client-id"`
|
||||
ClientJWK string `json:"client-jwk"`
|
||||
RedirectURI string `json:"redirect-uri"`
|
||||
WellKnownURL string `json:"well-known-url"`
|
||||
WellKnown IDPortenWellKnown `json:"well-known"`
|
||||
Locale string `json:"locale"`
|
||||
SecurityLevel string `json:"security-level"`
|
||||
ClientID string `json:"client-id"`
|
||||
ClientJWK string `json:"client-jwk"`
|
||||
RedirectURI string `json:"redirect-uri"`
|
||||
WellKnownURL string `json:"well-known-url"`
|
||||
WellKnown IDPortenWellKnown `json:"well-known"`
|
||||
Locale string `json:"locale"`
|
||||
SecurityLevel string `json:"security-level"`
|
||||
PostLogoutRedirectURI string `json:"post-logout-redirect-uri"`
|
||||
}
|
||||
|
||||
const (
|
||||
BindAddress = "bind-address"
|
||||
UpstreamHost = "upstream-host"
|
||||
LogFormat = "log-format"
|
||||
LogLevel = "log-level"
|
||||
IDPortenClientID = "idporten.client-id"
|
||||
IDPortenClientJWK = "idporten.client-jwk"
|
||||
IDPortenRedirectURI = "idporten.redirect-uri"
|
||||
IDPortenWellKnownURL = "idporten.well-known-url"
|
||||
IDPortenLocale = "idporten.locale"
|
||||
IDPortenSecurityLevel = "idporten.security-level"
|
||||
BindAddress = "bind-address"
|
||||
UpstreamHost = "upstream-host"
|
||||
LogFormat = "log-format"
|
||||
LogLevel = "log-level"
|
||||
IDPortenClientID = "idporten.client-id"
|
||||
IDPortenClientJWK = "idporten.client-jwk"
|
||||
IDPortenRedirectURI = "idporten.redirect-uri"
|
||||
IDPortenWellKnownURL = "idporten.well-known-url"
|
||||
IDPortenLocale = "idporten.locale"
|
||||
IDPortenSecurityLevel = "idporten.security-level"
|
||||
IDPortenPostLogoutRedirectURI = "idporten.post-logout-redirect-uri"
|
||||
)
|
||||
|
||||
func bindNAIS() {
|
||||
@@ -55,6 +57,7 @@ func Initialize() *Config {
|
||||
flag.String(UpstreamHost, "127.0.0.1:8080", "Address of upstream host.")
|
||||
flag.String(IDPortenSecurityLevel, "Level4", "Requested security level, either Level3 or Level4.")
|
||||
flag.String(IDPortenLocale, "nb", "Locale for OAuth2 consent screen.")
|
||||
flag.String(IDPortenPostLogoutRedirectURI, "https://nav.no", "URI for redirecting the user after successful logout at IDPorten.")
|
||||
|
||||
return &Config{}
|
||||
}
|
||||
|
||||
@@ -361,11 +361,52 @@ func (h *Handler) Default(w http.ResponseWriter, r *http.Request) {
|
||||
io.Copy(w, upstreamResponse.Body)
|
||||
}
|
||||
|
||||
// Logout triggers self-initiated for the current user
|
||||
func (h *Handler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
sessionCookie, err := r.Cookie(SessionCookieName)
|
||||
if err != nil {
|
||||
log.Tracef("no session cookie; should redirect to /oauth2/login")
|
||||
http.Redirect(w, r, "/oauth2/login", http.StatusTemporaryRedirect)
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := h.sessions[sessionCookie.Value]
|
||||
if !ok {
|
||||
log.Tracef("no token stored for session %s; needs garbage collection client side", sessionCookie.Value)
|
||||
http.Redirect(w, r, "/oauth2/login", http.StatusTemporaryRedirect)
|
||||
return
|
||||
}
|
||||
|
||||
delete(h.sessions, sessionCookie.Value)
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: SessionCookieName,
|
||||
Value: "",
|
||||
Path: "/",
|
||||
Expires: time.Unix(0,0),
|
||||
Secure: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
})
|
||||
|
||||
u, err := url.Parse(h.Config.WellKnown.EndSessionEndpoint)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
v := u.Query()
|
||||
v.Add("post_logout_redirect_uri", h.Config.PostLogoutRedirectURI)
|
||||
u.RawQuery = v.Encode()
|
||||
|
||||
http.Redirect(w, r, u.String(), http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func New(handler *Handler) chi.Router {
|
||||
r := chi.NewRouter()
|
||||
r.With(middleware.DefaultLogger)
|
||||
r.Get("/oauth2/login", handler.Login)
|
||||
r.Get("/oauth2/callback", handler.Callback)
|
||||
r.Get("/oauth2/logout_self", handler.Logout)
|
||||
r.HandleFunc("/*", handler.Default)
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user