mirror of
https://github.com/openziti/ziti.git
synced 2026-09-25 03:42:38 +00:00
69885639d3
- migrates from op.NewProvider() to LegacyServer/RegisterLegacyServer, routing all OIDC endpoint errors through op.WriteError which maps server_error to HTTP 500 and supports custom status codes via op.StatusError - returns oidc.ErrInvalidClient() from AuthorizeClientIDSecret for unknown clients and bad secrets (HTTP 400 with invalid_client) - returns oidc.ErrInvalidGrant() from parseRefreshToken, parseAccessToken, createAccessToken, and renewRefreshToken for client-supplied token errors (HTTP 400 with invalid_grant) - fixes copy-paste bug in parseAccessToken that reported "invalid refresh_token" for access token errors - plain Go errors from server-side failures (identity read, JSON marshal, token signing, Raft dispatch) now correctly surface as HTTP 500 via WriteError's DefaultToServerError handling - adds integration tests covering error codes for token endpoint, login endpoint, userinfo endpoint, and end_session endpoint
162 lines
6.1 KiB
Go
162 lines
6.1 KiB
Go
/*
|
|
Copyright NetFoundry Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package oidc_auth
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
|
"github.com/zitadel/oidc/v3/pkg/op"
|
|
)
|
|
|
|
// Client represents an OIDC Client and implements op.Client
|
|
type Client struct {
|
|
id string
|
|
secret string
|
|
redirectURIs []string
|
|
postLogoutRedirectURIs []string
|
|
applicationType op.ApplicationType
|
|
authMethod oidc.AuthMethod
|
|
loginURL func(string) string
|
|
responseTypes []oidc.ResponseType
|
|
grantTypes []oidc.GrantType
|
|
accessTokenType op.AccessTokenType
|
|
devMode bool
|
|
idTokenUserinfoClaimsAssertion bool
|
|
clockSkew time.Duration
|
|
idTokenDuration time.Duration
|
|
}
|
|
|
|
// GetID returns the clients id, implements op.Client
|
|
func (c *Client) GetID() string {
|
|
return c.id
|
|
}
|
|
|
|
// RedirectURIs returns an array of valid redirect URIs, implements op.Client
|
|
func (c *Client) RedirectURIs() []string {
|
|
return c.redirectURIs
|
|
}
|
|
|
|
// PostLogoutRedirectURIs returns an array of post logout redirect URIs, implements op.Client
|
|
func (c *Client) PostLogoutRedirectURIs() []string {
|
|
return c.postLogoutRedirectURIs
|
|
}
|
|
|
|
// RedirectURIGlobs must return the registered redirect_uris for Code and Implicit Flow that match via path.Match
|
|
func (c *Client) RedirectURIGlobs() []string {
|
|
return c.redirectURIs
|
|
}
|
|
|
|
// PostLogoutRedirectURIGlobs must return the registered post_logout_redirect_uris for sign-outs that match via path.Math
|
|
func (c *Client) PostLogoutRedirectURIGlobs() []string {
|
|
return []string{}
|
|
}
|
|
|
|
// ApplicationType returns the application type (app, native, user agent), implements op.Client
|
|
func (c *Client) ApplicationType() op.ApplicationType {
|
|
return c.applicationType
|
|
}
|
|
|
|
// AuthMethod returns the authentication method (client_secret_basic, client_secret_post, none, private_key_jwt), implements op.Client
|
|
func (c *Client) AuthMethod() oidc.AuthMethod {
|
|
return c.authMethod
|
|
}
|
|
|
|
// ResponseTypes returns all allowed response types (code, id_token token, id_token), these must match with the allowed grant types, implements op.Client
|
|
func (c *Client) ResponseTypes() []oidc.ResponseType {
|
|
return c.responseTypes
|
|
}
|
|
|
|
// GrantTypes returns all allowed grant types (authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:jwt-bearer), implements op.Client
|
|
func (c *Client) GrantTypes() []oidc.GrantType {
|
|
return c.grantTypes
|
|
}
|
|
|
|
// LoginURL returns the URL clients should be directed to for login based on authentication request id,
|
|
// implements op.Client
|
|
func (c *Client) LoginURL(id string) string {
|
|
return c.loginURL(id)
|
|
}
|
|
|
|
// AccessTokenType returns the type of access token the client uses (Bearer (opaque) or JWT), implements op.Client
|
|
func (c *Client) AccessTokenType() op.AccessTokenType {
|
|
return c.accessTokenType
|
|
}
|
|
|
|
// IDTokenLifetime returns the lifetime of the client's id_tokens
|
|
func (c *Client) IDTokenLifetime() time.Duration {
|
|
return c.idTokenDuration
|
|
}
|
|
|
|
// DevMode enables the use of non-compliant configs such as redirect_uris, implements op.Client
|
|
func (c *Client) DevMode() bool {
|
|
return c.devMode
|
|
}
|
|
|
|
// RestrictAdditionalIdTokenScopes allows specifying which custom scopes shall be asserted into the id_token, implements op.Client
|
|
func (c *Client) RestrictAdditionalIdTokenScopes() func(scopes []string) []string {
|
|
return func(scopes []string) []string {
|
|
return scopes
|
|
}
|
|
}
|
|
|
|
// RestrictAdditionalAccessTokenScopes allows specifying which custom scopes shall be asserted into the JWT access_token, implements op.Client
|
|
func (c *Client) RestrictAdditionalAccessTokenScopes() func(scopes []string) []string {
|
|
return func(scopes []string) []string {
|
|
return scopes
|
|
}
|
|
}
|
|
|
|
// IsScopeAllowed enables Client custom scopes validation, implements op.Client
|
|
// No custom scopes are currently supported.
|
|
func (c *Client) IsScopeAllowed(_ string) bool {
|
|
return false
|
|
}
|
|
|
|
// IDTokenUserinfoClaimsAssertion allows specifying if claims of scope profile, email, phone and address are asserted into the id_token
|
|
// even if an access token if issued which violates the OIDC Core spec
|
|
// (5.4. Requesting Claims using Scope Values: https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims)
|
|
// some clients though require that e.g. email is always in the id_token when requested even if an access_token is issued, implements op.Client
|
|
func (c *Client) IDTokenUserinfoClaimsAssertion() bool {
|
|
return c.idTokenUserinfoClaimsAssertion
|
|
}
|
|
|
|
// ClockSkew enables clients to instruct the OP to apply a clock skew on the various times and expirations
|
|
// (subtract from issued_at, add to expiration, ...), implements op.Client
|
|
func (c *Client) ClockSkew() time.Duration {
|
|
return c.clockSkew
|
|
}
|
|
|
|
// NativeClient will create a client of type native, which will always use PKCE and allow the use of refresh tokens
|
|
func NativeClient(id string, redirectURIs, postlogoutURIs []string) *Client {
|
|
return &Client{
|
|
id: id,
|
|
secret: "", //rely on PKCE
|
|
redirectURIs: redirectURIs,
|
|
postLogoutRedirectURIs: postlogoutURIs,
|
|
applicationType: op.ApplicationTypeNative,
|
|
authMethod: oidc.AuthMethodNone,
|
|
responseTypes: []oidc.ResponseType{oidc.ResponseTypeCode},
|
|
grantTypes: []oidc.GrantType{oidc.GrantTypeCode, oidc.GrantTypeRefreshToken, oidc.GrantTypeTokenExchange},
|
|
accessTokenType: op.AccessTokenTypeJWT,
|
|
devMode: false,
|
|
idTokenUserinfoClaimsAssertion: false,
|
|
clockSkew: 0,
|
|
idTokenDuration: 1 * time.Hour,
|
|
}
|
|
}
|