feat: Token Revocation, Request Object and OP Certification (#130)
FEATURES (and FIXES): - support OAuth 2.0 Token Revocation [RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009) - handle request object using `request` parameter [OIDC Core 1.0 Request Object](https://openid.net/specs/openid-connect-core-1_0.html#RequestObject) - handle response mode - added some information to the discovery endpoint: - revocation_endpoint (added with token revocation) - revocation_endpoint_auth_methods_supported (added with token revocation) - revocation_endpoint_auth_signing_alg_values_supported (added with token revocation) - token_endpoint_auth_signing_alg_values_supported (was missing) - introspection_endpoint_auth_signing_alg_values_supported (was missing) - request_object_signing_alg_values_supported (added with request object) - request_parameter_supported (added with request object) - fixed `removeUserinfoScopes ` now returns the scopes without "userinfo" scopes (profile, email, phone, addedd) [source diff](https://github.com/caos/oidc/pull/130/files#diff-fad50c8c0f065d4dbc49d6c6a38f09c992c8f5d651a479ba00e31b500543559eL170-R171) - improved error handling (pkg/oidc/error.go) and fixed some wrong OAuth errors (e.g. `invalid_grant` instead of `invalid_request`) - improved MarshalJSON and added MarshalJSONWithStatus - removed deprecated PEM decryption from `BytesToPrivateKey` [source diff](https://github.com/caos/oidc/pull/130/files#diff-fe246e428e399ccff599627c71764de51387b60b4df84c67de3febd0954e859bL11-L19) - NewAccessTokenVerifier now uses correct (internal) `accessTokenVerifier` [source diff](https://github.com/caos/oidc/pull/130/files#diff-3a01c7500ead8f35448456ef231c7c22f8d291710936cac91de5edeef52ffc72L52-R52) BREAKING CHANGE: - move functions from `utils` package into separate packages - added various methods to the (OP) `Configuration` interface [source diff](https://github.com/caos/oidc/pull/130/files#diff-2538e0dfc772fdc37f057aecd6fcc2943f516c24e8be794cce0e368a26d20a82R19-R32) - added revocationEndpoint to `WithCustomEndpoints ` [source diff](https://github.com/caos/oidc/pull/130/files#diff-19ae13a743eb7cebbb96492798b1bec556673eb6236b1387e38d722900bae1c3L355-R391) - remove unnecessary context parameter from JWTProfileExchange [source diff](https://github.com/caos/oidc/pull/130/files#diff-4ed8f6affa4a9631fa8a034b3d5752fbb6a819107141aae00029014e950f7b4cL14)
This commit is contained in:
parent
763d3334e7
commit
eb10752e48
63 changed files with 1738 additions and 624 deletions
64
pkg/op/op.go
64
pkg/op/op.go
|
@ -12,8 +12,8 @@ import (
|
|||
"golang.org/x/text/language"
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
|
||||
httphelper "github.com/caos/oidc/pkg/http"
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
"github.com/caos/oidc/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -23,6 +23,7 @@ const (
|
|||
defaultTokenEndpoint = "oauth/token"
|
||||
defaultIntrospectEndpoint = "oauth/introspect"
|
||||
defaultUserinfoEndpoint = "userinfo"
|
||||
defaultRevocationEndpoint = "revoke"
|
||||
defaultEndSessionEndpoint = "end_session"
|
||||
defaultKeysEndpoint = "keys"
|
||||
)
|
||||
|
@ -33,6 +34,7 @@ var (
|
|||
Token: NewEndpoint(defaultTokenEndpoint),
|
||||
Introspection: NewEndpoint(defaultIntrospectEndpoint),
|
||||
Userinfo: NewEndpoint(defaultUserinfoEndpoint),
|
||||
Revocation: NewEndpoint(defaultRevocationEndpoint),
|
||||
EndSession: NewEndpoint(defaultEndSessionEndpoint),
|
||||
JwksURI: NewEndpoint(defaultKeysEndpoint),
|
||||
}
|
||||
|
@ -41,8 +43,8 @@ var (
|
|||
type OpenIDProvider interface {
|
||||
Configuration
|
||||
Storage() Storage
|
||||
Decoder() utils.Decoder
|
||||
Encoder() utils.Encoder
|
||||
Decoder() httphelper.Decoder
|
||||
Encoder() httphelper.Encoder
|
||||
IDTokenHintVerifier() IDTokenHintVerifier
|
||||
AccessTokenVerifier() AccessTokenVerifier
|
||||
Crypto() Crypto
|
||||
|
@ -74,6 +76,7 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) *mux.Router
|
|||
router.Handle(o.TokenEndpoint().Relative(), intercept(tokenHandler(o)))
|
||||
router.HandleFunc(o.IntrospectionEndpoint().Relative(), introspectionHandler(o))
|
||||
router.HandleFunc(o.UserinfoEndpoint().Relative(), userinfoHandler(o))
|
||||
router.HandleFunc(o.RevocationEndpoint().Relative(), revocationHandler(o))
|
||||
router.Handle(o.EndSessionEndpoint().Relative(), intercept(endSessionHandler(o)))
|
||||
router.HandleFunc(o.KeysEndpoint().Relative(), keysHandler(o.Storage()))
|
||||
return router
|
||||
|
@ -84,8 +87,10 @@ type Config struct {
|
|||
CryptoKey [32]byte
|
||||
DefaultLogoutRedirectURI string
|
||||
CodeMethodS256 bool
|
||||
AuthMethodPost bool
|
||||
AuthMethodPrivateKeyJWT bool
|
||||
GrantTypeRefreshToken bool
|
||||
RequestObjectSupported bool
|
||||
SupportedUILocales []language.Tag
|
||||
}
|
||||
|
||||
|
@ -94,6 +99,7 @@ type endpoints struct {
|
|||
Token Endpoint
|
||||
Introspection Endpoint
|
||||
Userinfo Endpoint
|
||||
Revocation Endpoint
|
||||
EndSession Endpoint
|
||||
CheckSessionIframe Endpoint
|
||||
JwksURI Endpoint
|
||||
|
@ -148,7 +154,6 @@ type openidProvider struct {
|
|||
decoder *schema.Decoder
|
||||
encoder *schema.Encoder
|
||||
interceptors []HttpInterceptor
|
||||
retry func(int) (bool, int)
|
||||
timer <-chan time.Time
|
||||
}
|
||||
|
||||
|
@ -172,6 +177,10 @@ func (o *openidProvider) UserinfoEndpoint() Endpoint {
|
|||
return o.endpoints.Userinfo
|
||||
}
|
||||
|
||||
func (o *openidProvider) RevocationEndpoint() Endpoint {
|
||||
return o.endpoints.Revocation
|
||||
}
|
||||
|
||||
func (o *openidProvider) EndSessionEndpoint() Endpoint {
|
||||
return o.endpoints.EndSession
|
||||
}
|
||||
|
@ -181,7 +190,7 @@ func (o *openidProvider) KeysEndpoint() Endpoint {
|
|||
}
|
||||
|
||||
func (o *openidProvider) AuthMethodPostSupported() bool {
|
||||
return true //todo: config
|
||||
return o.config.AuthMethodPost
|
||||
}
|
||||
|
||||
func (o *openidProvider) CodeMethodS256Supported() bool {
|
||||
|
@ -192,6 +201,10 @@ func (o *openidProvider) AuthMethodPrivateKeyJWTSupported() bool {
|
|||
return o.config.AuthMethodPrivateKeyJWT
|
||||
}
|
||||
|
||||
func (o *openidProvider) TokenEndpointSigningAlgorithmsSupported() []string {
|
||||
return []string{"RS256"}
|
||||
}
|
||||
|
||||
func (o *openidProvider) GrantTypeRefreshTokenSupported() bool {
|
||||
return o.config.GrantTypeRefreshToken
|
||||
}
|
||||
|
@ -204,6 +217,30 @@ func (o *openidProvider) GrantTypeJWTAuthorizationSupported() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (o *openidProvider) IntrospectionAuthMethodPrivateKeyJWTSupported() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *openidProvider) IntrospectionEndpointSigningAlgorithmsSupported() []string {
|
||||
return []string{"RS256"}
|
||||
}
|
||||
|
||||
func (o *openidProvider) RevocationAuthMethodPrivateKeyJWTSupported() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *openidProvider) RevocationEndpointSigningAlgorithmsSupported() []string {
|
||||
return []string{"RS256"}
|
||||
}
|
||||
|
||||
func (o *openidProvider) RequestObjectSupported() bool {
|
||||
return o.config.RequestObjectSupported
|
||||
}
|
||||
|
||||
func (o *openidProvider) RequestObjectSigningAlgorithmsSupported() []string {
|
||||
return []string{"RS256"}
|
||||
}
|
||||
|
||||
func (o *openidProvider) SupportedUILocales() []language.Tag {
|
||||
return o.config.SupportedUILocales
|
||||
}
|
||||
|
@ -212,11 +249,11 @@ func (o *openidProvider) Storage() Storage {
|
|||
return o.storage
|
||||
}
|
||||
|
||||
func (o *openidProvider) Decoder() utils.Decoder {
|
||||
func (o *openidProvider) Decoder() httphelper.Decoder {
|
||||
return o.decoder
|
||||
}
|
||||
|
||||
func (o *openidProvider) Encoder() utils.Encoder {
|
||||
func (o *openidProvider) Encoder() httphelper.Encoder {
|
||||
return o.encoder
|
||||
}
|
||||
|
||||
|
@ -332,6 +369,16 @@ func WithCustomUserinfoEndpoint(endpoint Endpoint) Option {
|
|||
}
|
||||
}
|
||||
|
||||
func WithCustomRevocationEndpoint(endpoint Endpoint) Option {
|
||||
return func(o *openidProvider) error {
|
||||
if err := endpoint.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
o.endpoints.Revocation = endpoint
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithCustomEndSessionEndpoint(endpoint Endpoint) Option {
|
||||
return func(o *openidProvider) error {
|
||||
if err := endpoint.Validate(); err != nil {
|
||||
|
@ -352,11 +399,12 @@ func WithCustomKeysEndpoint(endpoint Endpoint) Option {
|
|||
}
|
||||
}
|
||||
|
||||
func WithCustomEndpoints(auth, token, userInfo, endSession, keys Endpoint) Option {
|
||||
func WithCustomEndpoints(auth, token, userInfo, revocation, endSession, keys Endpoint) Option {
|
||||
return func(o *openidProvider) error {
|
||||
o.endpoints.Authorization = auth
|
||||
o.endpoints.Token = token
|
||||
o.endpoints.Userinfo = userInfo
|
||||
o.endpoints.Revocation = revocation
|
||||
o.endpoints.EndSession = endSession
|
||||
o.endpoints.JwksURI = keys
|
||||
return nil
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue