token introspection

This commit is contained in:
Livio Amstutz 2021-02-03 10:42:01 +01:00
parent 4b426c899a
commit 345fc7e837
4 changed files with 28 additions and 35 deletions

View file

@ -30,9 +30,10 @@ type OPStorage interface {
AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string) error
SetUserinfoFromScopes(ctx context.Context, userinfo oidc.UserInfoSetter, userID, clientID string, scopes []string) error
SetUserinfoFromToken(ctx context.Context, userinfo oidc.UserInfoSetter, tokenID, subject, origin string) error
SetIntrospectionFromToken(ctx context.Context, userinfo oidc.IntrospectionResponse, tokenID, subject, callerTokenID, callerSubject string) error
GetPrivateClaimsFromScopes(ctx context.Context, userID, clientID string, scopes []string) (map[string]interface{}, error)
GetKeyByIDAndUserID(ctx context.Context, keyID, userID string) (*jose.JSONWebKey, error)
//ValidateJWTProfileScopes(ctx context.Context, userID string, scope oidc.Scopes) (oidc.Scopes, error)
ValidateJWTProfileScopes(ctx context.Context, userID string, scope oidc.Scopes) (oidc.Scopes, error)
//deprecated: use GetUserinfoFromScopes instead
GetUserinfoFromScopes(ctx context.Context, userID, clientID string, scopes []string) (oidc.UserInfo, error)

View file

@ -3,6 +3,7 @@ package op
import (
"errors"
"net/http"
"strings"
"github.com/caos/oidc/pkg/oidc"
"github.com/caos/oidc/pkg/utils"
@ -22,20 +23,24 @@ func introspectionHandler(introspector Introspector) func(http.ResponseWriter, *
}
func Introspect(w http.ResponseWriter, r *http.Request, introspector Introspector) {
//validate authorization
callerToken := r.Header.Get("authorization")
response := oidc.NewIntrospectionResponse()
token, err := ParseTokenInrospectionRequest(r, introspector.Decoder())
if err != nil {
utils.MarshalJSON(w, response)
return
}
tokenID, subject, ok := getTokenIDAndSubject(r.Context(), introspector, token)
callerToken, callerSubject, ok := getTokenIDAndSubject(r.Context(), introspector, strings.TrimPrefix(callerToken, oidc.PrefixBearer))
if !ok {
utils.MarshalJSON(w, response)
return
}
err = introspector.Storage().SetUserinfoFromToken(r.Context(), response, tokenID, subject, r.Header.Get("origin"))
introspectionToken, err := ParseTokenInrospectionRequest(r, introspector.Decoder())
if err != nil {
utils.MarshalJSON(w, response)
return
}
tokenID, subject, ok := getTokenIDAndSubject(r.Context(), introspector, introspectionToken)
if !ok {
utils.MarshalJSON(w, response)
return
}
err = introspector.Storage().SetIntrospectionFromToken(r.Context(), response, tokenID, subject, callerToken, callerSubject)
if err != nil {
utils.MarshalJSON(w, response)
return

View file

@ -191,9 +191,11 @@ func JWTProfile(w http.ResponseWriter, r *http.Request, exchanger JWTAuthorizati
return
}
//TODO: filter scopes
tokenRequest.Scopes = ValidateJWTProfileScopes(tokenRequest., profileRequest.Scope)
tokenRequest.Scopes, err = exchanger.Storage().ValidateJWTProfileScopes(r.Context(), tokenRequest.Issuer, profileRequest.Scope)
if err != nil {
RequestError(w, r, err)
return
}
resp, err := CreateJWTTokenResponse(r.Context(), tokenRequest, exchanger)
if err != nil {
RequestError(w, r, err)
@ -215,24 +217,6 @@ func ParseJWTProfileRequest(r *http.Request, decoder utils.Decoder) (*oidc.JWTPr
return tokenReq, nil
}
func ValidateJWTProfileScopes(client Client, scopes []string) []string {
for i := len(scopes) - 1; i >= 0; i-- {
scope := scopes[i]
if !(scope == oidc.ScopeOpenID ||
scope == oidc.ScopeProfile ||
scope == oidc.ScopeEmail ||
scope == oidc.ScopePhone ||
scope == oidc.ScopeAddress ||
scope == oidc.ScopeOfflineAccess) && //TODO: allowed
!client.IsScopeAllowed(scope) {
scopes[i] = scopes[len(scopes)-1]
scopes[len(scopes)-1] = ""
scopes = scopes[:len(scopes)-1]
}
}
return scopes
}
func TokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) {
tokenRequest, err := ParseTokenExchangeRequest(w, r)
if err != nil {