mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-06 12:52:53 +02:00
identity: support custom code flow request params (#998)
Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
parent
666420f4c9
commit
dbd1eac97f
7 changed files with 73 additions and 48 deletions
|
@ -182,6 +182,7 @@ func New(opts config.Options) (*Authenticate, error) {
|
|||
ClientSecret: opts.ClientSecret,
|
||||
Scopes: opts.Scopes,
|
||||
ServiceAccount: opts.ServiceAccount,
|
||||
AuthCodeOptions: opts.RequestParams,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -125,6 +125,13 @@ type Options struct {
|
|||
Scopes []string `mapstructure:"idp_scopes" yaml:"idp_scopes,omitempty"`
|
||||
ServiceAccount string `mapstructure:"idp_service_account" yaml:"idp_service_account,omitempty"`
|
||||
|
||||
// RequestParams are custom request params added to the signin request as
|
||||
// part of an Oauth2 code flow.
|
||||
//
|
||||
// https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml
|
||||
// https://openid.net/specs/openid-connect-basic-1_0.html#RequestParameters
|
||||
RequestParams map[string]string `mapstructure:"idp_request_params" yaml:"idp_request_params,omitempty"`
|
||||
|
||||
// Administrators contains a set of emails with users who have super user
|
||||
// (sudo) access including the ability to impersonate other users' access
|
||||
Administrators []string `mapstructure:"administrators" yaml:"administrators,omitempty"`
|
||||
|
@ -154,7 +161,6 @@ type Options struct {
|
|||
// RefreshCooldown limits the rate a user can refresh her session
|
||||
RefreshCooldown time.Duration `mapstructure:"refresh_cooldown" yaml:"refresh_cooldown,omitempty"`
|
||||
|
||||
//Routes map[string]string `mapstructure:"routes" yaml:"routes,omitempty"`
|
||||
DefaultUpstreamTimeout time.Duration `mapstructure:"default_upstream_timeout" yaml:"default_upstream_timeout,omitempty"`
|
||||
|
||||
// Address/Port to bind to for prometheus metrics
|
||||
|
|
|
@ -74,16 +74,11 @@ Autocert requires that ports `80`/`443` be accessible from the internet in order
|
|||
- Type: `bool`
|
||||
- Optional
|
||||
|
||||
If true, cause autocert to request a certificate with `status_request`
|
||||
extension (commonly called `Must-Staple`). This allows the TLS client
|
||||
(the browser) to fail immediately if the TLS handshake doesn't include
|
||||
OCSP stapling information. Only used when [Autocert](./#autocert) is
|
||||
true.
|
||||
If true, cause autocert to request a certificate with `status_request` extension (commonly called `Must-Staple`). This allows the TLS client (the browser) to fail immediately if the TLS handshake doesn't include OCSP stapling information. Only used when [Autocert](./#autocert) is true.
|
||||
|
||||
NOTE: this only takes effect the next time Pomerium renews your
|
||||
certificates.
|
||||
NOTE: this only takes effect the next time Pomerium renews your certificates.
|
||||
|
||||
See also https://tools.ietf.org/html/rfc7633 for more context.
|
||||
See also <https://tools.ietf.org/html/rfc7633> for more context.
|
||||
|
||||
### Autocert Directory
|
||||
|
||||
|
@ -294,8 +289,7 @@ spec:
|
|||
|
||||
#### Traefik docker-compose
|
||||
|
||||
If the `forward_auth_url` is also handled by Traefik, you will need to configure Traefik to trust the `X-Forwarded-*`
|
||||
headers as described in [the documentation](https://docs.traefik.io/v2.2/routing/entrypoints/#forwarded-headers).
|
||||
If the `forward_auth_url` is also handled by Traefik, you will need to configure Traefik to trust the `X-Forwarded-*` headers as described in [the documentation](https://docs.traefik.io/v2.2/routing/entrypoints/#forwarded-headers).
|
||||
|
||||
```yml
|
||||
version: "3"
|
||||
|
@ -487,9 +481,7 @@ pomerium_config_last_reload_success_timestamp | Gauge | The timestamp of the
|
|||
|
||||
#### Envoy Proxy Metrics
|
||||
|
||||
As of `v0.9`, Pomerium uses [envoy Proxy]([https://](https://www.envoyproxy.io/) for the data plane. As such, proxy related metrics are sourced
|
||||
from envoy, and use envoy's internal [stats data model](https://www.envoyproxy.io/docs/envoy/latest/operations/stats_overview). Please see Envoy's documentation for information
|
||||
about specific metrics.
|
||||
As of `v0.9`, Pomerium uses [envoy Proxy]([https://](https://www.envoyproxy.io/) for the data plane. As such, proxy related metrics are sourced from envoy, and use envoy's internal [stats data model](https://www.envoyproxy.io/docs/envoy/latest/operations/stats_overview). Please see Envoy's documentation for information about specific metrics.
|
||||
|
||||
All metrics coming from envoy will be labeled with `service="pomerium"` or `service="pomerium-proxy"`, depending if you're running all-in-one or distributed service mode.
|
||||
|
||||
|
@ -658,6 +650,22 @@ Identity Provider Service Account is field used to configure any additional user
|
|||
|
||||
Provider URL is the base path to an identity provider's [OpenID connect discovery document](https://openid.net/specs/openid-connect-discovery-1_0.html). For example, google's URL would be `https://accounts.google.com` for [their discover document](https://accounts.google.com/.well-known/openid-configuration).
|
||||
|
||||
### Identity Provider Request Params
|
||||
|
||||
- Environmental Variable: `IDP_REQUEST_PARAMS`
|
||||
- Config File Key: `idp_request_params`
|
||||
- Type: map of `strings` key value pairs
|
||||
- Optional
|
||||
|
||||
Request parameters to be added as part of a signin request using OAuth2 code flow.
|
||||
|
||||
For more information see:
|
||||
|
||||
- [OIDC Request Parameters](https://openid.net/specs/openid-connect-basic-1_0.html#RequestParameters)
|
||||
- [IANA OAuth Parameters](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml)
|
||||
- [Microsoft Azure Request params](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code)
|
||||
- [Google Authentication URI parameters](https://developers.google.com/identity/protocols/oauth2/openid-connect)
|
||||
|
||||
## Proxy Service
|
||||
|
||||
### Authenticate Service URL
|
||||
|
|
|
@ -29,4 +29,8 @@ type Options struct {
|
|||
// ServiceAccount can be set for those providers that require additional
|
||||
// credentials or tokens to do follow up API calls (e.g. Google)
|
||||
ServiceAccount string
|
||||
|
||||
// AuthCodeOptions specifies additional key value pairs query params to add
|
||||
// to the request flow signin url.
|
||||
AuthCodeOptions map[string]string
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/identity/oauth"
|
||||
pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc"
|
||||
)
|
||||
|
@ -21,6 +19,9 @@ const Name = "azure"
|
|||
// an sign in to the application.
|
||||
const defaultProviderURL = "https://login.microsoftonline.com/common"
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code
|
||||
var defaultAuthCodeOptions = map[string]string{"prompt": "select_account"}
|
||||
|
||||
// Provider is an Azure implementation of the Authenticator interface.
|
||||
type Provider struct {
|
||||
*pom_oidc.Provider
|
||||
|
@ -38,11 +39,11 @@ func New(ctx context.Context, o *oauth.Options) (*Provider, error) {
|
|||
return nil, fmt.Errorf("%s: failed creating oidc provider: %w", Name, err)
|
||||
}
|
||||
p.Provider = genericOidc
|
||||
return &p, nil
|
||||
|
||||
p.AuthCodeOptions = defaultAuthCodeOptions
|
||||
if len(o.AuthCodeOptions) != 0 {
|
||||
p.AuthCodeOptions = o.AuthCodeOptions
|
||||
}
|
||||
|
||||
// GetSignInURL returns the sign in url with typical oauth parameters
|
||||
// https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow
|
||||
func (p *Provider) GetSignInURL(state string) string {
|
||||
return p.Oauth.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "select_account"))
|
||||
return &p, nil
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
oidc "github.com/coreos/go-oidc"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/identity/oauth"
|
||||
pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc"
|
||||
|
@ -24,6 +23,9 @@ const (
|
|||
|
||||
var defaultScopes = []string{oidc.ScopeOpenID, "profile", "email"}
|
||||
|
||||
// https://developers.google.com/identity/protocols/oauth2/openid-connect#authenticationuriparameters
|
||||
var defaultAuthCodeOptions = map[string]string{"prompt": "select_account consent"}
|
||||
|
||||
// Provider is a Google implementation of the Authenticator interface.
|
||||
type Provider struct {
|
||||
*pom_oidc.Provider
|
||||
|
@ -45,20 +47,9 @@ func New(ctx context.Context, o *oauth.Options) (*Provider, error) {
|
|||
}
|
||||
p.Provider = genericOidc
|
||||
|
||||
p.AuthCodeOptions = defaultAuthCodeOptions
|
||||
if len(o.AuthCodeOptions) != 0 {
|
||||
p.AuthCodeOptions = o.AuthCodeOptions
|
||||
}
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// GetSignInURL returns a URL to OAuth 2.0 provider's consent page that asks for permissions for
|
||||
// the required scopes explicitly.
|
||||
// Google requires an additional access scope for offline access which is a requirement for any
|
||||
// application that needs to access a Google API when the user is not present.
|
||||
// Support for this scope differs between OpenID Connect providers. For instance
|
||||
// Google rejects it, favoring appending "access_type=offline" as part of the
|
||||
// authorization request instead.
|
||||
// Google only provide refresh_token on the first authorization from the user. If user clears
|
||||
// cookies, re-authorization will not bring back refresh_token. A work around to this is to add
|
||||
// prompt=consent to the OAuth redirect URL and will always return a refresh_token.
|
||||
// https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
||||
func (p *Provider) GetSignInURL(state string) string {
|
||||
return p.Oauth.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "select_account consent"))
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ const Name = "oidc"
|
|||
|
||||
var defaultScopes = []string{go_oidc.ScopeOpenID, "profile", "email", "offline_access"}
|
||||
|
||||
var defaultAuthCodeOptions = []oauth2.AuthCodeOption{oauth2.AccessTypeOffline}
|
||||
|
||||
// Provider provides a standard, OpenID Connect implementation
|
||||
// of an authorization identity provider.
|
||||
// https://openid.net/specs/openid-connect-core-1_0.html
|
||||
|
@ -45,6 +47,10 @@ type Provider struct {
|
|||
// providers that doesn't implement the revocation endpoint but a logout session.
|
||||
// https://openid.net/specs/openid-connect-frontchannel-1_0.html#RPInitiated
|
||||
EndSessionURL string `json:"end_session_endpoint,omitempty"`
|
||||
|
||||
// AuthCodeOptions specifies additional key value pairs query params to add
|
||||
// to the request flow signin url.
|
||||
AuthCodeOptions map[string]string
|
||||
}
|
||||
|
||||
// New creates a new instance of a generic OpenID Connect provider.
|
||||
|
@ -71,6 +77,10 @@ func New(ctx context.Context, o *oauth.Options) (*Provider, error) {
|
|||
RedirectURL: o.RedirectURL.String(),
|
||||
}
|
||||
|
||||
if len(o.AuthCodeOptions) != 0 {
|
||||
p.AuthCodeOptions = o.AuthCodeOptions
|
||||
}
|
||||
|
||||
// add non-standard claims like end-session, revoke, and user info
|
||||
if err := p.Provider.Claims(&p); err != nil {
|
||||
return nil, fmt.Errorf("identity/oidc: could not retrieve additional claims: %w", err)
|
||||
|
@ -86,7 +96,11 @@ func New(ctx context.Context, o *oauth.Options) (*Provider, error) {
|
|||
// the state query parameter on your redirect callback.
|
||||
// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
|
||||
func (p *Provider) GetSignInURL(state string) string {
|
||||
return p.Oauth.AuthCodeURL(state, oauth2.AccessTypeOffline)
|
||||
opts := defaultAuthCodeOptions
|
||||
for k, v := range p.AuthCodeOptions {
|
||||
opts = append(opts, oauth2.SetAuthURLParam(k, v))
|
||||
}
|
||||
return p.Oauth.AuthCodeURL(state, opts...)
|
||||
}
|
||||
|
||||
// Authenticate converts an authorization code returned from the identity
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue