Merge branch 'main' into extend-tracing
This commit is contained in:
commit
0ffd13c780
6 changed files with 71 additions and 23 deletions
2
go.mod
2
go.mod
|
@ -5,7 +5,7 @@ go 1.21
|
||||||
require (
|
require (
|
||||||
github.com/bmatcuk/doublestar/v4 v4.6.1
|
github.com/bmatcuk/doublestar/v4 v4.6.1
|
||||||
github.com/go-chi/chi/v5 v5.0.12
|
github.com/go-chi/chi/v5 v5.0.12
|
||||||
github.com/go-jose/go-jose/v3 v3.0.2
|
github.com/go-jose/go-jose/v3 v3.0.3
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/google/go-github/v31 v31.0.0
|
github.com/google/go-github/v31 v31.0.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.2 h1:2Edjn8Nrb44UvTdp84KU0bBPs1cO7noRCybtS3eJEUQ=
|
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||||
github.com/go-jose/go-jose/v3 v3.0.2/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
|
|
@ -4,7 +4,9 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/zitadel/oidc/v3/pkg/client"
|
"github.com/zitadel/oidc/v3/pkg/client"
|
||||||
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
@ -33,6 +35,17 @@ func NewTokenExchangerClientCredentials(ctx context.Context, issuer, clientID, c
|
||||||
return newOAuthTokenExchange(ctx, issuer, authorizer, options...)
|
return newOAuthTokenExchange(ctx, issuer, authorizer, options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTokenExchangerJWTProfile(ctx context.Context, issuer, clientID string, signer jose.Signer, options ...func(source *OAuthTokenExchange)) (TokenExchanger, error) {
|
||||||
|
authorizer := func() (any, error) {
|
||||||
|
assertion, err := client.SignedJWTProfileAssertion(clientID, []string{issuer}, time.Hour, signer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return client.ClientAssertionFormAuthorization(assertion), nil
|
||||||
|
}
|
||||||
|
return newOAuthTokenExchange(ctx, issuer, authorizer, options...)
|
||||||
|
}
|
||||||
|
|
||||||
func newOAuthTokenExchange(ctx context.Context, issuer string, authorizer func() (any, error), options ...func(source *OAuthTokenExchange)) (*OAuthTokenExchange, error) {
|
func newOAuthTokenExchange(ctx context.Context, issuer string, authorizer func() (any, error), options ...func(source *OAuthTokenExchange)) (*OAuthTokenExchange, error) {
|
||||||
te := &OAuthTokenExchange{
|
te := &OAuthTokenExchange{
|
||||||
httpClient: httphelper.DefaultHTTPClient,
|
httpClient: httphelper.DefaultHTTPClient,
|
||||||
|
|
|
@ -27,6 +27,11 @@ const (
|
||||||
SlowDown errorType = "slow_down"
|
SlowDown errorType = "slow_down"
|
||||||
AccessDenied errorType = "access_denied"
|
AccessDenied errorType = "access_denied"
|
||||||
ExpiredToken errorType = "expired_token"
|
ExpiredToken errorType = "expired_token"
|
||||||
|
|
||||||
|
// InvalidTarget error is returned by Token Exchange if
|
||||||
|
// the requested target or audience is invalid.
|
||||||
|
// [RFC 8693, Section 2.2.2: Error Response](https://www.rfc-editor.org/rfc/rfc8693#section-2.2.2)
|
||||||
|
InvalidTarget errorType = "invalid_target"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -112,6 +117,14 @@ var (
|
||||||
Description: "The \"device_code\" has expired.",
|
Description: "The \"device_code\" has expired.",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Token exchange error
|
||||||
|
ErrInvalidTarget = func() *Error {
|
||||||
|
return &Error{
|
||||||
|
ErrorType: InvalidTarget,
|
||||||
|
Description: "The requested audience or target is invalid.",
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
|
|
|
@ -47,6 +47,7 @@ type TokenClaims struct {
|
||||||
AuthorizedParty string `json:"azp,omitempty"`
|
AuthorizedParty string `json:"azp,omitempty"`
|
||||||
ClientID string `json:"client_id,omitempty"`
|
ClientID string `json:"client_id,omitempty"`
|
||||||
JWTID string `json:"jti,omitempty"`
|
JWTID string `json:"jti,omitempty"`
|
||||||
|
Actor *ActorClaims `json:"act,omitempty"`
|
||||||
|
|
||||||
// Additional information set by this framework
|
// Additional information set by this framework
|
||||||
SignatureAlg jose.SignatureAlgorithm `json:"-"`
|
SignatureAlg jose.SignatureAlgorithm `json:"-"`
|
||||||
|
@ -204,6 +205,28 @@ func (i *IDTokenClaims) UnmarshalJSON(data []byte) error {
|
||||||
return unmarshalJSONMulti(data, (*itcAlias)(i), &i.Claims)
|
return unmarshalJSONMulti(data, (*itcAlias)(i), &i.Claims)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActorClaims provides the `act` claims used for impersonation or delegation Token Exchange.
|
||||||
|
//
|
||||||
|
// An actor can be nested in case an obtained token is used as actor token to obtain impersonation or delegation.
|
||||||
|
// This allows creating a chain of actors.
|
||||||
|
// See [RFC 8693, section 4.1](https://www.rfc-editor.org/rfc/rfc8693#name-act-actor-claim).
|
||||||
|
type ActorClaims struct {
|
||||||
|
Actor *ActorClaims `json:"act,omitempty"`
|
||||||
|
Issuer string `json:"iss,omitempty"`
|
||||||
|
Subject string `json:"sub,omitempty"`
|
||||||
|
Claims map[string]any `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type acAlias ActorClaims
|
||||||
|
|
||||||
|
func (c *ActorClaims) MarshalJSON() ([]byte, error) {
|
||||||
|
return mergeAndMarshalClaims((*acAlias)(c), c.Claims)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ActorClaims) UnmarshalJSON(data []byte) error {
|
||||||
|
return unmarshalJSONMulti(data, (*acAlias)(c), &c.Claims)
|
||||||
|
}
|
||||||
|
|
||||||
type AccessTokenResponse struct {
|
type AccessTokenResponse struct {
|
||||||
AccessToken string `json:"access_token,omitempty" schema:"access_token,omitempty"`
|
AccessToken string `json:"access_token,omitempty" schema:"access_token,omitempty"`
|
||||||
TokenType string `json:"token_type,omitempty" schema:"token_type,omitempty"`
|
TokenType string `json:"token_type,omitempty" schema:"token_type,omitempty"`
|
||||||
|
@ -352,4 +375,8 @@ type TokenExchangeResponse struct {
|
||||||
ExpiresIn uint64 `json:"expires_in,omitempty"`
|
ExpiresIn uint64 `json:"expires_in,omitempty"`
|
||||||
Scopes SpaceDelimitedArray `json:"scope,omitempty"`
|
Scopes SpaceDelimitedArray `json:"scope,omitempty"`
|
||||||
RefreshToken string `json:"refresh_token,omitempty"`
|
RefreshToken string `json:"refresh_token,omitempty"`
|
||||||
|
|
||||||
|
// IDToken field allows returning an additional ID token
|
||||||
|
// if the requested_token_type was Access Token and scope contained openid.
|
||||||
|
IDToken string `json:"id_token,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package oidc
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
jose "github.com/go-jose/go-jose/v3"
|
jose "github.com/go-jose/go-jose/v3"
|
||||||
|
@ -57,13 +58,7 @@ var AllTokenTypes = []TokenType{
|
||||||
type TokenType string
|
type TokenType string
|
||||||
|
|
||||||
func (t TokenType) IsSupported() bool {
|
func (t TokenType) IsSupported() bool {
|
||||||
for _, tt := range AllTokenTypes {
|
return slices.Contains(AllTokenTypes, t)
|
||||||
if t == tt {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TokenRequest interface {
|
type TokenRequest interface {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue