Introduction
SAML (Security Assertion Markup Language) is a widely used protocol for Single Sign-On (SSO), allowing users to authenticate once and access multiple applications. In this article, we'll walk through implementing SAML authentication in a Domino application, detailing the steps needed to provide metadata, make the SSO call, and handle the assertion response (ACS call).
Prerequisites
Before you begin, ensure you have:
- Access to a SAML Identity Provider (IdP) such as Microsoft Azure AD or Okta.
- Basic knowledge of Java and HTTP requests.
- A configured Domino server with the capability to execute Java agents.
Step-by-Step Implementation
1. Providing Metadata
The first step in setting up SAML authentication is to provide metadata that the Identity Provider (IdP) and Service Provider (SP) can use for configuration. You’ll need to supply both IdP and SP metadata to the Domino application.
Basically it means you will need to make 2 public URL: https://yourdomain.com/meta/{id} that provide XML response (and that will be used by IdP) and additionally to that IdP sohuld provide their URL you are going work with.
You also need to find a suitable Java library that can provide your a SamlClient (I use https://github.com/lastpass/saml-sdk-java)
2. Making the SSO Call
Once the metadata is set, you can make the SSO request to the IdP. Here’s the code that generates the SAML authentication request and sends it to the IdP.
String idpURL = config.getItemValueString("IdPURL"); idpMeta = new URL(idpURL).openStream(); String spData = config.getItemValueString("MetaXML"); spMeta = new ByteArrayInputStream(spData.getBytes(StandardCharsets.UTF_8)); // 2. initialize saml client SAMLInit.initialize(); IdPConfig idpConfig = new IdPConfig(idpMeta); SPConfig spConfig = new SPConfig(spMeta); SAMLClient client = new SAMLClient(spConfig, idpConfig); // 3. send login request String requestId = SAMLUtils.generateRequestId(); String authrequest = client.generateAuthnRequest(requestId); String url = client.getIdPConfig().getLoginUrl() + "?SAMLRequest=" + URLEncoder.encode(authrequest, "UTF-8");
The SAMLClient
is used to generate the authentication request, and the resulting URL is the login endpoint where the user must be redirected.
3. Handling the Assertion Consumer Service (ACS) Call
After the user is authenticated by the IdP, the SAML response is sent back to the Domino server via the Assertion Consumer Service (ACS) endpoint. The following code handles this response and extracts user attributes from it.
String authresponse = web.getParam("AuthResponse"); String idpURL = config.getItemValueString("IdPURL"); String spData = config.getItemValueString("MetaXML"); SAMLInit.initialize(); IdPConfig idpConfig = new IdPConfig(idpMeta); SPConfig spConfig = new SPConfig(spMeta); SAMLClient client = new SAMLClient(spConfig, idpConfig); AttributeSet aset = client.validateResponse(authresponse); Map> attr = aset.getAttributes(); for (Map.Entry > entry : attr.entrySet()) { String key = entry.getKey(); List values = entry.getValue(); doc.replaceItemValue(key, new Vector<>(values)); }
This code validates the SAML response using the SAMLClient
, extracts the attributes (such as username, email, etc.), and stores them in the Domino document.
Conclusion
Implementing SAML authentication in Domino involves configuring metadata for the IdP and SP, making an authentication request, and handling the ACS call to process the response. While this example uses the LastPass SAML library, similar methods apply when using other libraries. The overall process is straightforward and can greatly improve the security and convenience of user authentication in your Domino applications.