diff --git a/Documentation/connectors/saml.md b/Documentation/connectors/saml.md index c9af0995e6..be29d394f7 100644 --- a/Documentation/connectors/saml.md +++ b/Documentation/connectors/saml.md @@ -6,8 +6,6 @@ The SAML provider allows authentication through the SAML 2.0 HTTP POST binding. The connector uses the value of the `NameID` element as the user's unique identifier which dex assumes is both unique and never changes. Use the `nameIDPolicyFormat` to ensure this is set to a value which satisfies these requirements. -Unlike some clients which will process unprompted AuthnResponses, dex must send the initial AuthnRequest and validates the response's InResponseTo value. - ## Caveats __The connector doesn't support refresh tokens__ since the SAML 2.0 protocol doesn't provide a way to requery a provider without interaction. If the "offline_access" scope is requested, it will be ignored. @@ -111,3 +109,44 @@ connectors: emailAttr: email groupsAttr: groups ``` + +## Identity Provider Initiated Login + +The SAML connector can support the identity provider (IdP) initiated flow with some special configuration. This flow allows a SAML user to initiate the login from a portal on their provider without needing to redirect back to the provider for further authentication. + +Because this flow does not follow the normal OAuth flow (App -> Auth Provider -> App), dex requires some configuration on the client to know how to handle an unprompted AuthnResponse. For each client that you would like to support SAML's IdP initiated flow, you must configure the `samlInitiated` section. + +As a static client: + +```yaml +staticClients: +- id: example-app + name: "Example App" + secret: ZXhhbXBsZS1hcHAtc2VjcmV0 + redirectURIs: + - http://127.0.0.1:5555/callback + samlInitiated: + redirecURI: http://127.0.0.1:5555/callback + scopes: ["openid", "profile", "email"] +``` + +Or via the API: + +```golang +client := &api.Client{ + Id: "example-app", + Name: "Example App", + Secret: "ZXhhbXBsZS1hcHAtc2VjcmV0", + RedirectUris: []string{"http://127.0.0.1:5555/callback"}, + SamlInitiated: &api.SamlInitiatedConfig{ + RedirectURI: "http://127.0.0.1:5555/callback", + Scopes: []string{"openid", "profile", "email"} + }, +} +``` + +The scopes above are optional. If they are not provided the default set `openid profile email groups` will be used. However, without `samlInitiated.redirecURI` dex will reject any IdP initiated login for that client. + +When configuring an application on your SAML provider, you must provide the `client_id` as the Default Relay Sate. This is how dex will match the AuthnResponse to the client, decide what claims to build, and where to redirect the user after handling the response. + +After handling the AuthnResponse dex will redirect back to your application with a `code` and an empty `state`. Your application must be willing to accept the empty `state` and redeem the `code` for user tokens. The implicit flow is not supported since there is no way of generating a verifiable `nonce` in this setup.