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.
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.
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.
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 here, 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. 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 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.
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.
Above are the current default values (not the recommended values) for the properties available to be set via keycloak.properties.
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.
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 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 clients, then it could be useful for locking down the server in combination with 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
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.
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
The following would be a recommended keycloak.properties file (if anonymous user access is also required)
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 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.
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.