func compareJWTs(a, b jose.JWT) string { if a.Encode() == b.Encode() { return "" } var aClaims, bClaims jose.Claims for _, j := range []struct { claims *jose.Claims jwt jose.JWT }{ {&aClaims, a}, {&bClaims, b}, } { var err error *j.claims, err = j.jwt.Claims() if err != nil { *j.claims = jose.Claims(map[string]interface{}{ "msg": "bad claims", "err": err, }) } } return diff.ObjectDiff(aClaims, bClaims) }
func handleTokenFunc(srv OIDCServer) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { w.Header().Set("Allow", "POST") phttp.WriteError(w, http.StatusMethodNotAllowed, fmt.Sprintf("POST only acceptable method")) return } err := r.ParseForm() if err != nil { log.Errorf("error parsing request: %v", err) writeTokenError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), "") return } state := r.PostForm.Get("state") user, password, ok := r.BasicAuth() if !ok { log.Errorf("error parsing basic auth") writeTokenError(w, oauth2.NewError(oauth2.ErrorInvalidClient), state) return } creds := oidc.ClientCredentials{ID: user, Secret: password} var jwt *jose.JWT var refreshToken string grantType := r.PostForm.Get("grant_type") switch grantType { case oauth2.GrantTypeAuthCode: code := r.PostForm.Get("code") if code == "" { log.Errorf("missing code param") writeTokenError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) return } jwt, refreshToken, err = srv.CodeToken(creds, code) if err != nil { log.Errorf("couldn't exchange code for token: %v", err) writeTokenError(w, err, state) return } case oauth2.GrantTypeClientCreds: jwt, err = srv.ClientCredsToken(creds) if err != nil { log.Errorf("couldn't creds for token: %v", err) writeTokenError(w, err, state) return } case oauth2.GrantTypeRefreshToken: token := r.PostForm.Get("refresh_token") if token == "" { writeTokenError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) return } jwt, err = srv.RefreshToken(creds, token) if err != nil { writeTokenError(w, err, state) return } default: log.Errorf("unsupported grant: %v", grantType) writeTokenError(w, oauth2.NewError(oauth2.ErrorUnsupportedGrantType), state) return } t := oAuth2Token{ AccessToken: jwt.Encode(), IDToken: jwt.Encode(), TokenType: "bearer", RefreshToken: refreshToken, } b, err := json.Marshal(t) if err != nil { log.Errorf("Failed marshaling %#v to JSON: %v", t, err) writeTokenError(w, oauth2.NewError(oauth2.ErrorServerError), state) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(b) } }