token introspection
This commit is contained in:
parent
4b426c899a
commit
345fc7e837
4 changed files with 28 additions and 35 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue