SAML

Security Assertion Markup Language (SAML) is an open standard where you can use one set of credentials to log in to many different websites.

As of Weave 2.6.5, SAML 2.0 is supported by Weave as a means of authenticating users.

SAML is the specification that outlines the steps required to perform the authentication but there are multiple different implementations of SAML Identity Providers (IdP), Weave itself is a SAML Service Provider (SP), this includes:

  • Active Directory Federation Services (ADFS) - a Single Sign-On (SSO) solution created by Microsoft

  • Azure Active Directory (Azure AD) - a cloud based SSO solution provided by Microsoft

  • Keycloak - an open source identity and access management solution provided by Red Hat

  • Cognito - an AWS identity provider solution provided by Amazon

  • Okta - a cloud based SAML identity provider created by Okta, Inc.

Weave itself uses the Keycloak Java library, which is different from the Keycloak identity provider listed above but is provided by the same team, for communicating with whichever SAML Identity Provider you wish to integrate with. This page documents how to configure Weave so that it will use this Keycloak library to communicate with your chosen SAML IdP.

Cookies

The SAML authentication process relies upon the caller having a valid “session”, both for the authentication process itself and when sending requests to the server after authentication (for requests that are required to be authenticated). Currently this session tracking requires the use of browser cookies.

Reverse Proxy

If there is a reverse proxy used in front of the Weave server then additional configuration must be setup for Weave to tell it that there is a reverse proxy. This should really be done for any Weave instance behind a reverse proxy but it is not required. However, if you’re using SAML authentication and the Weave server is behind a reverse proxy, then it is required that you perform this additional setup.

More information about setting up Weave when it’s behind a reverse proxy can be found here.

Note that for SAML authentication to work the context path exposed by the reverse proxy must be the same as that exposed by Weave. i.e. by default Weave is published at /weave but if you want to expose it as /maps normally you would have the reverse proxy expose /maps and forward the request to the Weave server at /weave, but this won’t work. You need to change the Weave server so that it also exposes Weave at /maps, and to do this you should edit the …\weave\jetty_base\webapps\weave.xml file and change the contextPath setting. Note that this also applies if you don’t want to use a context path for Weave and just expose it at /, just set the contextPath value to “/” in weave.xml in that case.

HTTPS

It is likely that the SAML Identity Provider you’re trying to integrate with Weave will require that the callback request it makes to the Weave server be made using a secure connection, meaning that the Weave server will have to be configured, and accessed by the user, via HTTPS rather than plain HTTP.

Acegi, Spring Security, Container and SAML

With the addition of SAML support, Weave now provides four methods of authenticating users. These methods are:

  • Acegi and Spring security which are configured using a single XML file, security.xml (or acegi.xml and spring.xml in Weave 2.6.5 or later).

  • Container based security, which is the default if no configuration file is available for the other authentication mechanisms. This method relies upon the underlying Web Application Server to perform the authentication.

  • And now SAML which requires two configuration files, keycloak.properties, a Weave specific configuration file documented in this page that you’re reading now just a little bit further down, and keycloak-saml.xml, a Keycloak specific XML configuration file documented here.

Note that configuring an application to authenticate with a SAML IdP requires specialist knowledge about SAML and the specific Identity Provider you’re using. This page is not intended to be a tutorial on SAML.

Disable/Enable Security Providers

Since you can only utilize a single security provider for a given Weave instance, the security provider is normally determined by the existence of its related configuration file, security.xml (or acegi.xml and spring.xml in 2.6.5+) for Acegi and Spring Security, keycloak.properties and keycloak-saml.xml for SAML, or nothing for container security.

But in some situations you may need to disable one or more of the installed security providers. One way to do this would be to remove the relevant com.cohga.server.security.acegi, com.cohga.server.security.spring, com.cohga.server.security.container or com.cohga.server.security.keycloak plugins from the …\weave\platform\plugins\ directory. But if that is not possible (for example if you’re running Weave from a Docker image that includes all the plugins and a default configuration file) you can also set a system property to disable one or more of the providers.

Setting the system properties weave.acegi.security, weave.spring.security, weave.container.security and/or weave.keycloak.security to false will disable the respective plugin from being used even if its configuration file(s) exist.

keycloak.properties

The keycloak.properties file is processed by Weave to determine some global settings required by Weave when authenticating incoming requests, like the name of the keycloak-saml.xml file if you don’t want to use the default name, or a list of URL’s that do not need to be authenticated.

allowAnonymous=false logRequests=false includePaths= excludePaths= includeBeforeExclude=false

Above are the current default values (not the recommended values) for the properties available to be set via keycloak.properties.

  • allowAnonymous

    • By default, every user will have to login before they can access anything. By setting allowAnonymous to true users can access Weave, as an anonymous user, without having to login.

  • logRequests

    • Certain HTTP headers are utilised when performing the SAML authentication process but logging those headers continually would pollute the Weave log with information that would be useless most of the time. So you can set logRequests to true while trying to debug authentication issues.

  • includePaths

    • includePaths can be set to a comma-separated list of URL patterns that should always be forced to be authenticated via SAML, even if allowAnonymous us set to true. Any request URL that matches one of the entries in includePaths will be required to be authenticated before it is processed by the server, either before the request is made or by performing the SAML authentication process as part of the request processing.

    • There’s no recommended value for the includePaths setting, but if you’re doing something like setting up a Weave server that’s just used by other servers and not as a user-facing Weave instance, then it could be useful for locking down the server in combination with excludePaths.

  • excludePaths

    • excludePaths can be set to a comma-separated list of URL patterns that should never be authenticated via SAML, even if allowAnonymous is set to false. This is for things like server health check URL’s that need to be made available to monitor the server and you don’t want/need to perform authentication before processing the request.

    • The recommended value for excludePaths is: /metrics,/server/ping,/server/healthcheck,/server/health.do./server/mq.do

  • includeBeforeExclude

    • Normally Weave checks the excludePaths list before the includePaths list to determine if a given request should be forced to be authenticated or forced to not be authenticated. You can reverse this check so that includePaths is checked first then excludePaths by setting includeBeforeExclude to true.

    • This setting is provided because both includePaths and excludePaths can include wildcards and you may wish to include a more permissive value in one list whilst including a more specific value(s) in the other list. By providing this setting, you can determine which list it is easier make permissive and which one to make more specific.

  • roleFilter.*

    • You can add a number of roleFilter entries to ensure that a user has a particular roles before they can access the given url.

    • Any suffix can be used for the filter name, and the values are applied in alphabetical order based on the filter name (not the order listed)

    • The value for each filter should contain a URL path to match followed by an equals sign followed by a comma-separated list of roles that the user must have at least one of before they can access the given path

    • This should be done for at least the Admin UI (replacing ROLE_ADMIN with the role that admin users will have)

    • This is only available with version 12.0.4 or later of the Keycloak security plugin

  • userProperties

    • The path to a user properties file that can be used to replace the roles assigned to users

    • If the user is listed in this file then the roles assigned in this file will completely replace those provide by the SAML server, that is, there is currently no way to assign additional roles, or remove individual roles from those provided by the SAML server.

    • The file should contain a single line for each user in the format:

      • username@domain.name=role1,role2,…,roleN

    • Note that that is assuming that the usernames returned from the SAML server contain a domain, e.g. @domain.name in the above example, if the SAML server isn’t returning the domain in the username then it does not need to be included in the user properties file.

    • If one of the roles, or the only role, listed for the user is “disabled” then the user will be provided with no roles, this can be used to override what’s in the SAML server and disable access for the user

  • userPropertiesHasPassword

    • If the user properties file specified by the userProperties setting has been copied from an existing users.properties file then file will likely contain passwords that aren’t used by Keycloak and should be ignored as a “role” assigned to the user when reading the file. So if this property is set to “true” then it indicates that the Keycloak user properties file does contain a password and the password should be ignored, but if this property either isn’t set or is set to anything other than “true” then it indicates that the Keycloak user properties file does not contain a password

  • userPropertiesHasDomain

    • This flag indicates that the usernames stored in the Keycloak user properties file contain a domain for the user, i.e. the user is listed as “user@example.com=…” rather than just “user=…”.

    • Most times the username returned from the SAML server will contain the domain and the Keycloak user properties file should be setup so that each user entry also contains a domain, this setting is primarily intended to make it easy to migrate an existing users.properties file, and can likely be ignored if you’re creating a new Keycloak user properties file from scratch, in which case you’d include the full username, including the domain, in the file

    • If this property is set to “true” or not set at all then it’s assumed that the Keycloak user properties file contains the domain for a user, if this property is set to “false” then it’s assumed that the Keycloak user properties file does not contain a domain for the user, which may be the case if the file is copied from an existing users.properties file.

    • This may be required to be explicitly set to false if you’re copying an existing users.properties file that doesn’t contain a domain but the SAML server is returning usernames that do contain a domain. Note that this assumes that the user names listed in the file (without a domain) are unique, which may not be the case, in which case the file should be updated to include the domain for each user and this property not be set (or set to true).

  • defaultRoles

    • A comma-separated list of roles that the user will be assigned if the SAML provider does not return any roles when the user logs in.

    • This does not effect anonymous logins, anonymous users won’t get any additional roles, and doesn’t allow users who are not able to authenticate via SAML any access.

    • This is useful if you want to use SAML authentication to restrict access to Weave, so users have to log in, but you don’t use any special roles (e.g. everyone just gets ROLE_USER) to then alter what the user has access to and don’t want to or can’t to setup all of the role in the SAML provider.

  • stripDomain

    • If the user name is an email address and you want to remove the domain from the email address for the username (and don’t want to or can’t do it via the SAML provider) then you can set this to true to have Weave remove the email domain from the email address.

The following would be a recommended keycloak.properties file (if anonymous user access is also required)

allowAnonymous=true excludePaths=/metrics,\ /server/ping,\ /server/healthcheck,\ /server/health.do,\ /server/mq.do,\ /report/remote,\ /**/favicon.ico roleFilter.1=/admin.*=ROLE_ADMIN roleFilter.2=/admin/**=ROLE_ADMIN

Note: The role of ROLE_ADMIN above is an example only. Replace it with the role which should be granted access to the Admin UI.

keycloak-saml.xml

keycloak-saml.xml (it can also be called just keycloak.xml) is the Keycloak specific XML configuration file documented here. The settings you need to specify in that file will be determined by the identity provider you’re using and will likely require assistance from someone familiar with that particular identity provider but is something that Cohga can provide assistance with.

One thing to note from the documentation linked above is that when it refers to external files, for example, a Java keystore containing certificates required to protect/verify communications with the SAML server, it’s assuming that those files are embedded within a “web application” and references those files relative to a WEB-INF directory. However, for Weave, those files are located adjacent to the keystore.properties file so do not require that the files are referenced relative to a WEB-INF directory.

Note that a number of values in the keycloak-saml.xml that reference external files, mostly related to various certificate and private keys, can instead be directly embedded in the file, as base64 encoded strings. This can make maintenance of the file easier by limiting the number of files that need to be tracked. For example KeyStore\PrivateKey vs PrivateKeyPem.

Some additional notes about keycloak-saml.xml settings

Some settings in keycloak-saml.xml will have an effect on Weave if not set correctly.

  • autodetectBearerOnly

    • This must be set to true. If set to true it will allow the Weave client, and any other “client” that uses the Weave REST API, to determine that a request sent to the server requires authentication before it will be processed. If the value is not set to true then a request that requires authentication would likely be redirected to a HTML page to start the authentication process, which is not what you want when using a REST API.