chore: document non-standard glob client (#328)
* op: correct typo rename checkURIAginstRedirects to checkURIAgainstRedirects * chore: document standard deviation when using globs add example on how to toggle the underlying client implementation based on DevMode. --------- Co-authored-by: David Sharnoff <dsharnoff@singlestore.com>
This commit is contained in:
parent
e1d50faf9b
commit
b7d18bfd02
4 changed files with 37 additions and 16 deletions
|
@ -32,6 +32,8 @@ type Client struct {
|
||||||
devMode bool
|
devMode bool
|
||||||
idTokenUserinfoClaimsAssertion bool
|
idTokenUserinfoClaimsAssertion bool
|
||||||
clockSkew time.Duration
|
clockSkew time.Duration
|
||||||
|
postLogoutRedirectURIGlobs []string
|
||||||
|
redirectURIGlobs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetID must return the client_id
|
// GetID must return the client_id
|
||||||
|
@ -44,21 +46,11 @@ func (c *Client) RedirectURIs() []string {
|
||||||
return c.redirectURIs
|
return c.redirectURIs
|
||||||
}
|
}
|
||||||
|
|
||||||
// RedirectURIGlobs provide wildcarding for additional valid redirects
|
|
||||||
func (c *Client) RedirectURIGlobs() []string {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostLogoutRedirectURIs must return the registered post_logout_redirect_uris for sign-outs
|
// PostLogoutRedirectURIs must return the registered post_logout_redirect_uris for sign-outs
|
||||||
func (c *Client) PostLogoutRedirectURIs() []string {
|
func (c *Client) PostLogoutRedirectURIs() []string {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostLogoutRedirectURIGlobs provide extra wildcarding for additional valid redirects
|
|
||||||
func (c *Client) PostLogoutRedirectURIGlobs() []string {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplicationType must return the type of the client (app, native, user agent)
|
// ApplicationType must return the type of the client (app, native, user agent)
|
||||||
func (c *Client) ApplicationType() op.ApplicationType {
|
func (c *Client) ApplicationType() op.ApplicationType {
|
||||||
return c.applicationType
|
return c.applicationType
|
||||||
|
@ -200,3 +192,26 @@ func WebClient(id, secret string, redirectURIs ...string) *Client {
|
||||||
clockSkew: 0,
|
clockSkew: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type hasRedirectGlobs struct {
|
||||||
|
*Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// RedirectURIGlobs provide wildcarding for additional valid redirects
|
||||||
|
func (c hasRedirectGlobs) RedirectURIGlobs() []string {
|
||||||
|
return c.redirectURIGlobs
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostLogoutRedirectURIGlobs provide extra wildcarding for additional valid redirects
|
||||||
|
func (c hasRedirectGlobs) PostLogoutRedirectURIGlobs() []string {
|
||||||
|
return c.postLogoutRedirectURIGlobs
|
||||||
|
}
|
||||||
|
|
||||||
|
// RedirectGlobsClient wraps the client in a op.HasRedirectGlobs
|
||||||
|
// only if DevMode is enabled.
|
||||||
|
func RedirectGlobsClient(client *Client) op.Client {
|
||||||
|
if client.devMode {
|
||||||
|
return hasRedirectGlobs{client}
|
||||||
|
}
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
|
@ -418,7 +418,7 @@ func (s *Storage) GetClientByClientID(ctx context.Context, clientID string) (op.
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("client not found")
|
return nil, fmt.Errorf("client not found")
|
||||||
}
|
}
|
||||||
return client, nil
|
return RedirectGlobsClient(client), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthorizeClientIDSecret implements the op.Storage interface
|
// AuthorizeClientIDSecret implements the op.Storage interface
|
||||||
|
|
|
@ -274,9 +274,9 @@ func ValidateAuthReqScopes(client Client, scopes []string) ([]string, error) {
|
||||||
return scopes, nil
|
return scopes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkURIAginstRedirects just checks aginst the valid redirect URIs and ignores
|
// checkURIAgainstRedirects just checks aginst the valid redirect URIs and ignores
|
||||||
// other factors.
|
// other factors.
|
||||||
func checkURIAginstRedirects(client Client, uri string) error {
|
func checkURIAgainstRedirects(client Client, uri string) error {
|
||||||
if str.Contains(client.RedirectURIs(), uri) {
|
if str.Contains(client.RedirectURIs(), uri) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -303,12 +303,12 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res
|
||||||
"Please ensure it is added to the request. If you have any questions, you may contact the administrator of the application.")
|
"Please ensure it is added to the request. If you have any questions, you may contact the administrator of the application.")
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(uri, "https://") {
|
if strings.HasPrefix(uri, "https://") {
|
||||||
return checkURIAginstRedirects(client, uri)
|
return checkURIAgainstRedirects(client, uri)
|
||||||
}
|
}
|
||||||
if client.ApplicationType() == ApplicationTypeNative {
|
if client.ApplicationType() == ApplicationTypeNative {
|
||||||
return validateAuthReqRedirectURINative(client, uri, responseType)
|
return validateAuthReqRedirectURINative(client, uri, responseType)
|
||||||
}
|
}
|
||||||
if err := checkURIAginstRedirects(client, uri); err != nil {
|
if err := checkURIAgainstRedirects(client, uri); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(uri, "http://") {
|
if strings.HasPrefix(uri, "http://") {
|
||||||
|
@ -329,7 +329,7 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res
|
||||||
func validateAuthReqRedirectURINative(client Client, uri string, responseType oidc.ResponseType) error {
|
func validateAuthReqRedirectURINative(client Client, uri string, responseType oidc.ResponseType) error {
|
||||||
parsedURL, isLoopback := HTTPLoopbackOrLocalhost(uri)
|
parsedURL, isLoopback := HTTPLoopbackOrLocalhost(uri)
|
||||||
isCustomSchema := !strings.HasPrefix(uri, "http://")
|
isCustomSchema := !strings.HasPrefix(uri, "http://")
|
||||||
if err := checkURIAginstRedirects(client, uri); err == nil {
|
if err := checkURIAgainstRedirects(client, uri); err == nil {
|
||||||
if client.DevMode() {
|
if client.DevMode() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,12 @@ type Client interface {
|
||||||
// interpretation. Redirect URIs that match either the non-glob version or the
|
// interpretation. Redirect URIs that match either the non-glob version or the
|
||||||
// glob version will be accepted. Glob URIs are only partially supported for native
|
// glob version will be accepted. Glob URIs are only partially supported for native
|
||||||
// clients: "http://" is not allowed except for loopback or in dev mode.
|
// clients: "http://" is not allowed except for loopback or in dev mode.
|
||||||
|
//
|
||||||
|
// Note that globbing / wildcards are not permitted by the OIDC
|
||||||
|
// standard and implementing this interface can have security implications.
|
||||||
|
// It is advised to only return a client of this type in rare cases,
|
||||||
|
// such as DevMode for the client being enabled.
|
||||||
|
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
||||||
type HasRedirectGlobs interface {
|
type HasRedirectGlobs interface {
|
||||||
RedirectURIGlobs() []string
|
RedirectURIGlobs() []string
|
||||||
PostLogoutRedirectURIGlobs() []string
|
PostLogoutRedirectURIGlobs() []string
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue