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

@ -6,8 +6,6 @@ import (
"time" "time"
"golang.org/x/text/language" "golang.org/x/text/language"
"github.com/caos/oidc/pkg/utils"
) )
type IntrospectionRequest struct { type IntrospectionRequest struct {
@ -230,11 +228,16 @@ func (i *introspectionResponse) MarshalJSON() ([]byte, error) {
return b, nil return b, nil
} }
claims, err := json.Marshal(i.claims) err = json.Unmarshal(b, &i.claims)
if err != nil { if err != nil {
return nil, fmt.Errorf("jws: invalid map of custom claims %v", i.claims) return nil, fmt.Errorf("jws: invalid map of custom claims %v", i.claims)
} }
return utils.ConcatenateJSON(b, claims)
return json.Marshal(i.claims)
//if err != nil {
// return nil, fmt.Errorf("jws: invalid map of custom claims %v", i.claims)
//}
//return utils.ConcatenateJSON(b, claims)
} }
func (i *introspectionResponse) UnmarshalJSON(data []byte) error { func (i *introspectionResponse) UnmarshalJSON(data []byte) error {

View file

@ -30,9 +30,10 @@ type OPStorage interface {
AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string) error AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string) error
SetUserinfoFromScopes(ctx context.Context, userinfo oidc.UserInfoSetter, userID, clientID string, scopes []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 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) GetPrivateClaimsFromScopes(ctx context.Context, userID, clientID string, scopes []string) (map[string]interface{}, error)
GetKeyByIDAndUserID(ctx context.Context, keyID, userID string) (*jose.JSONWebKey, 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 //deprecated: use GetUserinfoFromScopes instead
GetUserinfoFromScopes(ctx context.Context, userID, clientID string, scopes []string) (oidc.UserInfo, error) GetUserinfoFromScopes(ctx context.Context, userID, clientID string, scopes []string) (oidc.UserInfo, error)

View file

@ -3,6 +3,7 @@ package op
import ( import (
"errors" "errors"
"net/http" "net/http"
"strings"
"github.com/caos/oidc/pkg/oidc" "github.com/caos/oidc/pkg/oidc"
"github.com/caos/oidc/pkg/utils" "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) { func Introspect(w http.ResponseWriter, r *http.Request, introspector Introspector) {
//validate authorization callerToken := r.Header.Get("authorization")
response := oidc.NewIntrospectionResponse() response := oidc.NewIntrospectionResponse()
token, err := ParseTokenInrospectionRequest(r, introspector.Decoder()) callerToken, callerSubject, ok := getTokenIDAndSubject(r.Context(), introspector, strings.TrimPrefix(callerToken, oidc.PrefixBearer))
if err != nil {
utils.MarshalJSON(w, response)
return
}
tokenID, subject, ok := getTokenIDAndSubject(r.Context(), introspector, token)
if !ok { if !ok {
utils.MarshalJSON(w, response) utils.MarshalJSON(w, response)
return 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 { if err != nil {
utils.MarshalJSON(w, response) utils.MarshalJSON(w, response)
return return

View file

@ -191,9 +191,11 @@ func JWTProfile(w http.ResponseWriter, r *http.Request, exchanger JWTAuthorizati
return return
} }
//TODO: filter scopes tokenRequest.Scopes, err = exchanger.Storage().ValidateJWTProfileScopes(r.Context(), tokenRequest.Issuer, profileRequest.Scope)
tokenRequest.Scopes = ValidateJWTProfileScopes(tokenRequest., profileRequest.Scope) if err != nil {
RequestError(w, r, err)
return
}
resp, err := CreateJWTTokenResponse(r.Context(), tokenRequest, exchanger) resp, err := CreateJWTTokenResponse(r.Context(), tokenRequest, exchanger)
if err != nil { if err != nil {
RequestError(w, r, err) RequestError(w, r, err)
@ -215,24 +217,6 @@ func ParseJWTProfileRequest(r *http.Request, decoder utils.Decoder) (*oidc.JWTPr
return tokenReq, nil 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) { func TokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) {
tokenRequest, err := ParseTokenExchangeRequest(w, r) tokenRequest, err := ParseTokenExchangeRequest(w, r)
if err != nil { if err != nil {