Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Improve the sample config for SSO (OIDC, SAML, and CAS) #8635

Merged
merged 4 commits into from
Oct 30, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8635.doc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve the sample configuration for single sign-on providers.
127 changes: 77 additions & 50 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1505,10 +1505,8 @@ trusted_key_servers:

## Single sign-on integration ##

# Enable SAML2 for registration and login. Uses pysaml2.
#
# At least one of `sp_config` or `config_path` must be set in this section to
# enable SAML login.
# The following settings can be used to make Synapse use a single sign-on
# provider for authentication, instead of its internal password database.
#
# You will probably also want to set the following options to `false` to
# disable the regular login/registration flows:
Expand All @@ -1517,6 +1515,11 @@ trusted_key_servers:
#
# You will also want to investigate the settings under the "sso" configuration
# section below.

# Enable SAML2 for registration and login. Uses pysaml2.
#
# At least one of `sp_config` or `config_path` must be set in this section to
# enable SAML login.
#
# Once SAML support is enabled, a metadata file will be exposed at
# https://<server>:<port>/_matrix/saml2/metadata.xml, which you may be able to
Expand All @@ -1525,47 +1528,52 @@ trusted_key_servers:
# https://<server>:<port>/_matrix/saml2/authn_response.
#
saml2_config:
# Uncomment the following to enable authorization against a SAML server.
# Defaults to true, but is unused unless sp_config exists.
#
#enabled: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was omitted because it seemed to be redundant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it is a little confusing. OIDC did the reasonable thing and defaults this to false unless it exists, so was trying to make it consistent. I can remove it if you'd like.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OIDC did the reasonable thing and defaults this to false unless it exists, so was trying to make it consistent

In the past, I've waged a bit of a war on enabled options: my feeling is that you should just omit the section if you don't want that functionality. So I'm not convinced that is the reasonable thing, and hence leaving the enabled setting undocumented here.

In short, I'd vote for leaving it undocumented.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Reasonable" meaning that if it exists it should default to disabled. I'm OK removing this section though.


# `sp_config` is the configuration for the pysaml2 Service Provider.
# See pysaml2 docs for format of config.
#
# Default values will be used for the 'entityid' and 'service' settings,
# so it is not normally necessary to specify them unless you need to
# override them.
#
#sp_config:
# # point this to the IdP's metadata. You can use either a local file or
# # (preferably) a URL.
# metadata:
# #local: ["saml2/idp.xml"]
# remote:
# - url: https://our_idp/metadata.xml
#
# # By default, the user has to go to our login page first. If you'd like
# # to allow IdP-initiated login, set 'allow_unsolicited: true' in a
# # 'service.sp' section:
# #
# #service:
# # sp:
# # allow_unsolicited: true
#
# # The examples below are just used to generate our metadata xml, and you
# # may well not need them, depending on your setup. Alternatively you
# # may need a whole lot more detail - see the pysaml2 docs!
#
# description: ["My awesome SP", "en"]
# name: ["Test SP", "en"]
#
# organization:
# name: Example com
# display_name:
# - ["Example co", "en"]
# url: "http://example.com"
#
# contact_person:
# - given_name: Bob
# sur_name: "the Sysadmin"
# email_address": ["admin@example.com"]
# contact_type": technical
sp_config:
# point this to the IdP's metadata. You can use either a local file or
# (preferably) a URL.
#metadata:
clokep marked this conversation as resolved.
Show resolved Hide resolved
# local: ["saml2/idp.xml"]
# remote:
# - url: https://our_idp/metadata.xml
clokep marked this conversation as resolved.
Show resolved Hide resolved

# By default, the user has to go to our login page first. If you'd like
# to allow IdP-initiated login, set 'allow_unsolicited: true' in a
# 'service.sp' section:
#
#service:
# sp:
# allow_unsolicited: true

# The examples below are just used to generate our metadata xml, and you
# may well not need them, depending on your setup. Alternatively you
# may need a whole lot more detail - see the pysaml2 docs!

#description: ["My awesome SP", "en"]
#name: ["Test SP", "en"]

#organization:
# name: Example com
# display_name:
# - ["Example co", "en"]
# url: "http://example.com"

#contact_person:
# - given_name: Bob
# sur_name: "the Sysadmin"
# email_address": ["admin@example.com"]
# contact_type": technical

# Instead of putting the config inline as above, you can specify a
# separate pysaml2 configuration file:
Expand Down Expand Up @@ -1641,11 +1649,10 @@ saml2_config:
# value: "sales"


# OpenID Connect integration. The following settings can be used to make Synapse
# use an OpenID Connect Provider for authentication, instead of its internal
# password database.
# Enable OpenID Connect (OIDC) / OAuth 2.0 for registration and login.
#
# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md.
# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md
# for some example configurations.
#
oidc_config:
# Uncomment the following to enable authorization against an OpenID Connect
Expand Down Expand Up @@ -1778,15 +1785,35 @@ oidc_config:



# Enable CAS for registration and login.
# Enable Central Authentication Service (CAS) for registration and login.
#
#cas_config:
# enabled: true
# server_url: "https://cas-server.com"
# service_url: "https://homeserver.domain.com:8448"
# #displayname_attribute: name
# #required_attributes:
# # name: value
cas_config:
# Uncomment the following to enable authorization against a CAS server.
# Defaults to false.
#enabled: true

# The URL of the CAS authorization endpoint.
#
#server_url: "https://cas-server.com"

# The public URL of the homeserver.
#
#service_url: "https://homeserver.domain.com:8448"

# The attribute of the CAS response to use as the display name.
#
# If unset, no displayname will be set.
#
#displayname_attribute: name

# It is possible to configure Synapse to only allow logins if CAS attributes
# match particular values. All of the keys in the mapping below must exist
# and the values must match the given value. Alternately if the given value
# is None then any value is allowed (the attribute just must exist).
# All of the listed attributes must match for the login to be permitted.
#required_attributes:
clokep marked this conversation as resolved.
Show resolved Hide resolved
# userGroup: "staff"
# department: None


# Additional settings to use with single-sign on systems such as OpenID Connect,
Expand Down
44 changes: 32 additions & 12 deletions synapse/config/cas.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,48 @@ class CasConfig(Config):

def read_config(self, config, **kwargs):
cas_config = config.get("cas_config", None)
if cas_config:
self.cas_enabled = cas_config.get("enabled", True)
self.cas_enabled = cas_config and cas_config.get("enabled", True)

if self.cas_enabled:
self.cas_server_url = cas_config["server_url"]
self.cas_service_url = cas_config["service_url"]
self.cas_displayname_attribute = cas_config.get("displayname_attribute")
self.cas_required_attributes = cas_config.get("required_attributes", {})
self.cas_required_attributes = cas_config.get("required_attributes") or {}
else:
self.cas_enabled = False
self.cas_server_url = None
self.cas_service_url = None
self.cas_displayname_attribute = None
self.cas_required_attributes = {}

def generate_config_section(self, config_dir_path, server_name, **kwargs):
return """
# Enable CAS for registration and login.
# Enable Central Authentication Service (CAS) for registration and login.
#
#cas_config:
# enabled: true
# server_url: "https://cas-server.com"
# service_url: "https://homeserver.domain.com:8448"
# #displayname_attribute: name
# #required_attributes:
# # name: value
cas_config:
# Uncomment the following to enable authorization against a CAS server.
# Defaults to false.
#enabled: true

# The URL of the CAS authorization endpoint.
#
#server_url: "https://cas-server.com"

# The public URL of the homeserver.
#
#service_url: "https://homeserver.domain.com:8448"
Comment on lines +56 to +58
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this example is bad, the redirect and ticket endpoints are both registered as part of ClientRestResource, so I think the port being here is confusing?

(Changing the code to use public_baseurl is #7198.)


# The attribute of the CAS response to use as the display name.
#
# If unset, no displayname will be set.
#
#displayname_attribute: name

# It is possible to configure Synapse to only allow logins if CAS attributes
# match particular values. All of the keys in the mapping below must exist
# and the values must match the given value. Alternately if the given value
# is None then any value is allowed (the attribute just must exist).
# All of the listed attributes must match for the login to be permitted.
Comment on lines +66 to +70
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cribbed this from the saml2_config.attribute_requirements section, but I think I updated it to make sense.

Unfortunately this has a reversed name and works slightly differently. 😢

#required_attributes:
# userGroup: "staff"
# department: None
"""
7 changes: 3 additions & 4 deletions synapse/config/oidc_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,10 @@ def read_config(self, config, **kwargs):

def generate_config_section(self, config_dir_path, server_name, **kwargs):
return """\
# OpenID Connect integration. The following settings can be used to make Synapse
# use an OpenID Connect Provider for authentication, instead of its internal
# password database.
# Enable OpenID Connect (OIDC) / OAuth 2.0 for registration and login.
#
# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md.
# See https://github.com/matrix-org/synapse/blob/master/docs/openid.md
# for some example configurations.
#
oidc_config:
# Uncomment the following to enable authorization against an OpenID Connect
Expand Down
84 changes: 46 additions & 38 deletions synapse/config/saml2_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,8 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
return """\
## Single sign-on integration ##

# Enable SAML2 for registration and login. Uses pysaml2.
#
# At least one of `sp_config` or `config_path` must be set in this section to
# enable SAML login.
# The following settings can be used to make Synapse use a single sign-on
# provider for authentication, instead of its internal password database.
#
# You will probably also want to set the following options to `false` to
# disable the regular login/registration flows:
Expand All @@ -228,6 +226,11 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
#
# You will also want to investigate the settings under the "sso" configuration
# section below.

# Enable SAML2 for registration and login. Uses pysaml2.
#
# At least one of `sp_config` or `config_path` must be set in this section to
# enable SAML login.
Comment on lines +230 to +233
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this section down since the bits above apply to all of the SSO code. I actually wonder if it should be part of the sso_config class and that should go before SAML/OIDC/CAS? 🤷

#
# Once SAML support is enabled, a metadata file will be exposed at
# https://<server>:<port>/_matrix/saml2/metadata.xml, which you may be able to
Expand All @@ -236,47 +239,52 @@ def generate_config_section(self, config_dir_path, server_name, **kwargs):
# https://<server>:<port>/_matrix/saml2/authn_response.
#
saml2_config:
# Uncomment the following to enable authorization against a SAML server.
# Defaults to true, but is unused unless sp_config exists.
#
#enabled: true

# `sp_config` is the configuration for the pysaml2 Service Provider.
# See pysaml2 docs for format of config.
#
# Default values will be used for the 'entityid' and 'service' settings,
# so it is not normally necessary to specify them unless you need to
# override them.
#
#sp_config:
# # point this to the IdP's metadata. You can use either a local file or
# # (preferably) a URL.
# metadata:
# #local: ["saml2/idp.xml"]
# remote:
# - url: https://our_idp/metadata.xml
#
# # By default, the user has to go to our login page first. If you'd like
# # to allow IdP-initiated login, set 'allow_unsolicited: true' in a
# # 'service.sp' section:
# #
# #service:
# # sp:
# # allow_unsolicited: true
#
# # The examples below are just used to generate our metadata xml, and you
# # may well not need them, depending on your setup. Alternatively you
# # may need a whole lot more detail - see the pysaml2 docs!
#
# description: ["My awesome SP", "en"]
# name: ["Test SP", "en"]
#
# organization:
# name: Example com
# display_name:
# - ["Example co", "en"]
# url: "http://example.com"
#
# contact_person:
# - given_name: Bob
# sur_name: "the Sysadmin"
# email_address": ["admin@example.com"]
# contact_type": technical
sp_config:
# point this to the IdP's metadata. You can use either a local file or
# (preferably) a URL.
#metadata:
# local: ["saml2/idp.xml"]
# remote:
# - url: https://our_idp/metadata.xml

# By default, the user has to go to our login page first. If you'd like
# to allow IdP-initiated login, set 'allow_unsolicited: true' in a
# 'service.sp' section:
#
#service:
# sp:
# allow_unsolicited: true

# The examples below are just used to generate our metadata xml, and you
# may well not need them, depending on your setup. Alternatively you
# may need a whole lot more detail - see the pysaml2 docs!

#description: ["My awesome SP", "en"]
#name: ["Test SP", "en"]

#organization:
# name: Example com
# display_name:
# - ["Example co", "en"]
# url: "http://example.com"

#contact_person:
# - given_name: Bob
# sur_name: "the Sysadmin"
# email_address": ["admin@example.com"]
# contact_type": technical

# Instead of putting the config inline as above, you can specify a
# separate pysaml2 configuration file:
Expand Down