// Reads the OIDC JWT passed in the context and verifies it using the given OIDC client. // Returns the verified identity on success, error otherwise. func VerifiedIdentityFromContext(client *gooidc.Client, ctx context.Context) (*gooidc.Identity, error) { md, ok := metadata.FromContext(ctx) if !ok { return nil, errors.New("missing RPC credentials") } rawJWT, ok := md["jwt"] if !ok { return nil, errors.New("missing OIDC credentials") } if len(rawJWT) != 1 { return nil, errors.New("incorrect JWT data sent") } jwt, err := jose.ParseJWT(rawJWT[0]) if err != nil { return nil, err } if err := client.VerifyJWT(jwt); err != nil { return nil, err } claims, err := jwt.Claims() if err != nil { return nil, err } return gooidc.IdentityFromClaims(claims) }
// Parses and validates a JWT token, based on the client definition provided. func ValidateJWT(idToken string, client *oidc.Client) (jose.JWT, error) { jwt, err := jose.ParseJWT(idToken) if err != nil { return jose.JWT{}, err } return jwt, client.VerifyJWT(jwt) }
func handleCallbackFunc(c *oidc.Client, claims *jose.Claims, refresh *string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { code := r.URL.Query().Get("code") if code == "" { phttp.WriteError(w, http.StatusBadRequest, "code query param must be set") return } oac, err := c.OAuthClient() if err != nil { phttp.WriteError(w, http.StatusInternalServerError, fmt.Sprintf("unable to create oauth client: %v", err)) return } t, err := oac.RequestToken(oauth2.GrantTypeAuthCode, code) if err != nil { phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify auth code with issuer: %v", err)) return } // Get id token and claims. tok, err := jose.ParseJWT(t.IDToken) if err != nil { phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to parse id_token: %v", err)) return } if err := c.VerifyJWT(tok); err != nil { phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to verify the JWT: %v", err)) return } if *claims, err = tok.Claims(); err != nil { phttp.WriteError(w, http.StatusBadRequest, fmt.Sprintf("unable to construct claims: %v", err)) return } // Get refresh token. *refresh = t.RefreshToken w.WriteHeader(http.StatusOK) } }