mirror of
https://github.com/grafana/grafana.git
synced 2025-01-26 16:27:02 -06:00
SAML Single Logout (#27995)
* SAML: single logout WIP * SAML: sign SAML requests * SAML: remove unnecessary logs * fix go mod file * Docs: Single Logout * SAML: use api endpoint for single logout * Apply suggestions from code review Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> * SAML: save context for single logout * Chore: add SAML dependencies Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
parent
46a91f2b94
commit
b55a51e270
@ -41,24 +41,26 @@ In terms of initiation:
|
||||
|
||||
The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables]({{< relref "../administration/configuration.md#configure-with-environment-variables" >}}).
|
||||
|
||||
| Setting | Required | Description | Default |
|
||||
| ----------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------- | ------------- |
|
||||
| Setting | Required | Description | Default |
|
||||
| ----------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------- | ------------- |
|
||||
| `enabled` | No | Whether SAML authentication is allowed | `false` |
|
||||
| `single_logout` | No | Whether SAML Single Logout enabled | `false` |
|
||||
| `certificate` or `certificate_path` | Yes | Base64-encoded string or Path for the SP X.509 certificate | |
|
||||
| `private_key` or `private_key_path` | Yes | Base64-encoded string or Path for the SP private key | |
|
||||
| `signature_algorithm` | No | Signature algorithm used for signing requests to the IdP. Supported values are rsa-sha1, rsa-sha256, rsa-sha512. | |
|
||||
| `idp_metadata`, `idp_metadata_path`, or `idp_metadata_url` | Yes | Base64-encoded string, Path or URL for the IdP SAML metadata XML | |
|
||||
| `max_issue_delay` | No | Duration, since the IdP issued a response and the SP is allowed to process it | `90s` |
|
||||
| `metadata_valid_duration` | No | Duration, for how long the SP metadata is valid | `48h` |
|
||||
| `assertion_attribute_name` | No | Friendly name or name of the attribute within the SAML assertion to use as the user name | `displayName` |
|
||||
| `assertion_attribute_login` | No | Friendly name or name of the attribute within the SAML assertion to use as the user login handle | `mail` |
|
||||
| `assertion_attribute_email` | No | Friendly name or name of the attribute within the SAML assertion to use as the user email | `mail` |
|
||||
| `assertion_attribute_groups` | No | Friendly name or name of the attribute within the SAML assertion to use as the user groups | |
|
||||
| `assertion_attribute_role` | No | Friendly name or name of the attribute within the SAML assertion to use as the user roles | |
|
||||
| `assertion_attribute_org` | No | Friendly name or name of the attribute within the SAML assertion to use as the user organization | |
|
||||
| `metadata_valid_duration` | No | Duration, for how long the SP metadata is valid | `48h` |
|
||||
| `assertion_attribute_name` | No | Friendly name or name of the attribute within the SAML assertion to use as the user name | `displayName` |
|
||||
| `assertion_attribute_login` | No | Friendly name or name of the attribute within the SAML assertion to use as the user login handle | `mail` |
|
||||
| `assertion_attribute_email` | No | Friendly name or name of the attribute within the SAML assertion to use as the user email | `mail` |
|
||||
| `assertion_attribute_groups` | No | Friendly name or name of the attribute within the SAML assertion to use as the user groups | |
|
||||
| `assertion_attribute_role` | No | Friendly name or name of the attribute within the SAML assertion to use as the user roles | |
|
||||
| `assertion_attribute_org` | No | Friendly name or name of the attribute within the SAML assertion to use as the user organization | |
|
||||
| `allowed_organizations` | No | List of comma- or space-separated organizations. User should be a member of at least one organization to log in. | |
|
||||
| `org_mapping` | No | List of comma- or space-separated Organization:OrgId mappings | |
|
||||
| `role_values_editor` | No | List of comma- or space-separated roles which will be mapped into the Editor role | |
|
||||
| `role_values_admin` | No | List of comma- or space-separated roles which will be mapped into the Admin role | |
|
||||
| `org_mapping` | No | List of comma- or space-separated Organization:OrgId mappings | |
|
||||
| `role_values_editor` | No | List of comma- or space-separated roles which will be mapped into the Editor role | |
|
||||
| `role_values_admin` | No | List of comma- or space-separated roles which will be mapped into the Admin role | |
|
||||
| `role_values_grafana_admin` | No | List of comma- or space-separated roles which will be mapped into the Grafana Admin (Super Admin) role | |
|
||||
|
||||
### Enable SAML authentication
|
||||
@ -77,6 +79,10 @@ Grafana supports two ways of specifying both the `certificate` and `private_key`
|
||||
|
||||
You can only use one form of each configuration option. Using multiple forms, such as both `certificate` and `certificate_path`, results in an error.
|
||||
|
||||
### Signature algorithm
|
||||
|
||||
The SAML standard recommends using digital signature for some types of messages, like authentication or logout requests. If `signature_algorithm` option configured, Grafana will put digital signature into SAML requests. Supported signature types are `rsa-sha1`, `rsa-sha256`, `rsa-sha512`. This option should match your IdP configuration, otherwise, signature won't be validated by the IdP. Grafana uses key and certificate configured with `private_key` and `certificate` options for signing SAML requests.
|
||||
|
||||
### IdP metadata
|
||||
|
||||
You also need to define the public part of the IdP for message verification. The SAML IdP metadata XML defines where and how Grafana exchanges user information.
|
||||
@ -107,6 +113,10 @@ The integration provides two key endpoints as part of Grafana:
|
||||
- The `/saml/metadata` endpoint, which contains the SP metadata. You can either download and upload it manually, or youmake the IdP request it directly from the endpoint. Some providers name it Identifier or Entity ID.
|
||||
- The `/saml/acs` endpoint, which is intended to receive the ACS (Assertion Customer Service) callback. Some providers name it SSO URL or Reply URL.
|
||||
|
||||
### Single Logout
|
||||
|
||||
Single Logout feature allows user to log out from all applications associated with current IdP session established via SAML SSO. If `single_logout` option set to `true` and user logs out, Grafana requests IdP to terminate user session. Then IdP triggers logout process for all other applications which user logged in with the same IdP session (application should support single logout). And conversely, if another application connected to the same IdP initiates single logout, Grafana gets logout request from IdP and terminates user session.
|
||||
|
||||
### Assertion mapping
|
||||
|
||||
During the SAML SSO authentication flow, Grafana receives the ACS callback. The callback contains all the relevant information of the user under authentication embedded in the SAML response. Grafana parses the response to create (or update) the user within its internal database.
|
||||
|
3
go.mod
3
go.mod
@ -16,6 +16,7 @@ require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f
|
||||
github.com/aws/aws-sdk-go v1.33.12
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/benbjohnson/clock v0.0.0-20161215174838-7dc76406b6d3
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b
|
||||
github.com/centrifugal/centrifuge v0.11.0
|
||||
@ -67,7 +68,7 @@ require (
|
||||
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967
|
||||
github.com/robfig/cron/v3 v3.0.0
|
||||
github.com/russellhaering/goxmldsig v0.0.0-20200902171629-2e1fbc2c5593 // indirect
|
||||
github.com/russellhaering/goxmldsig v0.0.0-20200902171629-2e1fbc2c5593
|
||||
github.com/smartystreets/goconvey v1.6.4
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf
|
||||
|
@ -254,6 +254,11 @@ func (hs *HTTPServer) loginUserWithUser(user *models.User, c *models.ReqContext)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) Logout(c *models.ReqContext) {
|
||||
if hs.Cfg.SAMLEnabled && hs.Cfg.SAMLSingleLogoutEnabled {
|
||||
c.Redirect(setting.AppSubUrl + "/logout/saml")
|
||||
return
|
||||
}
|
||||
|
||||
if err := hs.AuthTokenService.RevokeToken(c.Req.Context(), c.UserToken); err != nil && err != models.ErrUserTokenNotFound {
|
||||
hs.log.Error("failed to revoke auth token", "error", err)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
// Upgrade ldapsync from cron to cron.v3 and
|
||||
// remove the cron (v1) dependency
|
||||
|
||||
_ "github.com/beevik/etree"
|
||||
_ "github.com/crewjam/saml"
|
||||
_ "github.com/gobwas/glob"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
_ "github.com/pkg/errors"
|
||||
_ "github.com/robfig/cron"
|
||||
_ "github.com/robfig/cron/v3"
|
||||
_ "github.com/russellhaering/goxmldsig"
|
||||
_ "github.com/stretchr/testify/require"
|
||||
_ "github.com/timberio/go-datemath"
|
||||
_ "gopkg.in/square/go-jose.v2"
|
||||
|
@ -287,7 +287,8 @@ type Cfg struct {
|
||||
OAuthCookieMaxAge int
|
||||
|
||||
// SAML Auth
|
||||
SAMLEnabled bool
|
||||
SAMLEnabled bool
|
||||
SAMLSingleLogoutEnabled bool
|
||||
|
||||
// Dataproxy
|
||||
SendUserHeader bool
|
||||
@ -998,6 +999,7 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) {
|
||||
|
||||
// SAML auth
|
||||
cfg.SAMLEnabled = iniFile.Section("auth.saml").Key("enabled").MustBool(false)
|
||||
cfg.SAMLSingleLogoutEnabled = iniFile.Section("auth.saml").Key("single_logout").MustBool(false)
|
||||
|
||||
// anonymous access
|
||||
AnonymousEnabled = iniFile.Section("auth.anonymous").Key("enabled").MustBool(false)
|
||||
|
Loading…
Reference in New Issue
Block a user