Skip to content
Snippets Groups Projects
Commit b82ed482 authored by Christian Pointner's avatar Christian Pointner
Browse files

oidc: parsing userinfo

parent 659b9c4d
No related branches found
No related tags found
No related merge requests found
...@@ -26,6 +26,7 @@ package auth ...@@ -26,6 +26,7 @@ package auth
import ( import (
"context" "context"
"encoding/json"
"net/http" "net/http"
oidc "github.com/coreos/go-oidc" oidc "github.com/coreos/go-oidc"
...@@ -130,6 +131,11 @@ type oidcCallbackHandler struct { ...@@ -130,6 +131,11 @@ type oidcCallbackHandler struct {
backend *OIDCBackend backend *OIDCBackend
} }
func invalidateSessionCookie(w http.ResponseWriter) {
// TODO: this needs to improve
http.SetCookie(w, &http.Cookie{Name: SessionCookieName, Value: "invalid", MaxAge: -1})
}
func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
sc, err := r.Cookie(SessionCookieName) sc, err := r.Cookie(SessionCookieName)
if sc == nil || err != nil { if sc == nil || err != nil {
...@@ -138,6 +144,7 @@ func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) ...@@ -138,6 +144,7 @@ func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }
s := auth.sessions.get(sc.Value) s := auth.sessions.get(sc.Value)
if s == nil { if s == nil {
invalidateSessionCookie(w)
http.Error(w, "invalid session cookie or session already expired", http.StatusUnauthorized) http.Error(w, "invalid session cookie or session already expired", http.StatusUnauthorized)
return return
} }
...@@ -151,37 +158,64 @@ func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) ...@@ -151,37 +158,64 @@ func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
} }
if r.URL.Query().Get("state") != s.oidc.State { if r.URL.Query().Get("state") != s.oidc.State {
invalidateSessionCookie(w)
auth.sessions.remove(sc.Value)
http.Error(w, "OIDC: state did not match", http.StatusBadRequest) http.Error(w, "OIDC: state did not match", http.StatusBadRequest)
return return
} }
oauth2Token, err := h.backend.oauth2Config.Exchange(r.Context(), r.URL.Query().Get("code")) oauth2Token, err := h.backend.oauth2Config.Exchange(r.Context(), r.URL.Query().Get("code"))
if err != nil { if err != nil {
http.Error(w, "OIDC: failed to exchange token: "+err.Error(), http.StatusInternalServerError) invalidateSessionCookie(w)
auth.sessions.remove(sc.Value)
http.Error(w, "OIDC: failed to exchange token: "+err.Error(), http.StatusBadRequest)
return return
} }
rawIDToken, ok := oauth2Token.Extra("id_token").(string) rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok { if !ok {
invalidateSessionCookie(w)
auth.sessions.remove(sc.Value)
http.Error(w, "OIDC: no id_token field in oauth2 token.", http.StatusInternalServerError) http.Error(w, "OIDC: no id_token field in oauth2 token.", http.StatusInternalServerError)
return return
} }
// Verify the ID Token signature and nonce. // Verify the ID Token signature and nonce.
idToken, err := h.backend.verifier.Verify(r.Context(), rawIDToken) idToken, err := h.backend.verifier.Verify(r.Context(), rawIDToken)
if err != nil { if err != nil {
invalidateSessionCookie(w)
auth.sessions.remove(sc.Value)
http.Error(w, "OIDC: failed to verify ID Token: "+err.Error(), http.StatusInternalServerError) http.Error(w, "OIDC: failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
return return
} }
if idToken.Nonce != s.oidc.Nonce { if idToken.Nonce != s.oidc.Nonce {
invalidateSessionCookie(w)
auth.sessions.remove(sc.Value)
http.Error(w, "OIDC: invalid ID token nonce", http.StatusInternalServerError) http.Error(w, "OIDC: invalid ID token nonce", http.StatusInternalServerError)
return return
} }
// TODO: parse userInfo, populeate new session and update it inside the session-manager userInfo, err := h.backend.provider.UserInfo(r.Context(), oauth2.StaticTokenSource(oauth2Token))
if err != nil {
invalidateSessionCookie(w)
auth.sessions.remove(sc.Value)
http.Error(w, "OIDC: failed to get userinfo: "+err.Error(), http.StatusInternalServerError)
return
}
resp := struct {
OAuth2Token *oauth2.Token
UserInfo *json.RawMessage
}{oauth2Token, new(json.RawMessage)}
// userInfo, err := h.backend.provider.UserInfo(r.Context(), oauth2.StaticTokenSource(oauth2Token)) if err := userInfo.Claims(&resp.UserInfo); err != nil {
// if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError)
// http.Error(w, "OIDC: failed to get userinfo: "+err.Error(), http.StatusInternalServerError) return
// return }
// }
data, err := json.MarshalIndent(resp, "", " ")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(data)
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment