BREAKING CHANGE: - The various verifier types are merged into a oidc.Verifir. - oidc.Verfier became a struct with exported fields * use type aliases for oidc.Verifier this binds the correct contstructor to each verifier usecase. * fix: handle the zero cases for oidc.Time * add unit tests to oidc verifier * fix: correct returned field for JWTTokenRequest JWTTokenRequest.GetIssuedAt() was returning the ExpiresAt field. This change corrects that by returning IssuedAt instead.
67 lines
1.8 KiB
Go
67 lines
1.8 KiB
Go
package op
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
|
|
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
|
)
|
|
|
|
type Introspector interface {
|
|
Decoder() httphelper.Decoder
|
|
Crypto() Crypto
|
|
Storage() Storage
|
|
AccessTokenVerifier(context.Context) *AccessTokenVerifier
|
|
}
|
|
|
|
type IntrospectorJWTProfile interface {
|
|
Introspector
|
|
JWTProfileVerifier(context.Context) JWTProfileVerifier
|
|
}
|
|
|
|
func introspectionHandler(introspector Introspector) func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
Introspect(w, r, introspector)
|
|
}
|
|
}
|
|
|
|
func Introspect(w http.ResponseWriter, r *http.Request, introspector Introspector) {
|
|
response := new(oidc.IntrospectionResponse)
|
|
token, clientID, err := ParseTokenIntrospectionRequest(r, introspector)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
tokenID, subject, ok := getTokenIDAndSubject(r.Context(), introspector, token)
|
|
if !ok {
|
|
httphelper.MarshalJSON(w, response)
|
|
return
|
|
}
|
|
err = introspector.Storage().SetIntrospectionFromToken(r.Context(), response, tokenID, subject, clientID)
|
|
if err != nil {
|
|
httphelper.MarshalJSON(w, response)
|
|
return
|
|
}
|
|
response.Active = true
|
|
httphelper.MarshalJSON(w, response)
|
|
}
|
|
|
|
func ParseTokenIntrospectionRequest(r *http.Request, introspector Introspector) (token, clientID string, err error) {
|
|
clientID, authenticated, err := ClientIDFromRequest(r, introspector)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
if !authenticated {
|
|
return "", "", oidc.ErrInvalidClient().WithParent(ErrNoClientCredentials)
|
|
}
|
|
|
|
req := new(oidc.IntrospectionRequest)
|
|
err = introspector.Decoder().Decode(req, r.Form)
|
|
if err != nil {
|
|
return "", "", errors.New("unable to parse request")
|
|
}
|
|
|
|
return req.Token, clientID, nil
|
|
}
|