This library implements a very simple SAML 2.0 client that allows retrieving an authenticated identity from a compliant identity provider, using the HTTP POST binding.
It is based on the OpenSAML library, and only provides the necessary glue code to make it work in a basic scenario. This is by no means a complete implementation supporting all the nitty gritty SAML details, but it does perform the basic task of generating requests and validating responses. It's useful if you need to authenticate with SAML but don't want to bring in an uber large framework such as Spring Security.
In order to work, the library must be provided with the xml metadata information that can be obtained from the identity provider. It is also possible to initialize it by directly providing the required values.
As of now, I've tested the library with ADFS and Okta as identity providers.
Add this dependency to your
pom.xml to reference the library:
<dependency> <groupId>com.coveo</groupId> <artifactId>saml-client</artifactId> <version>3.0.2</version> </dependency>
An SAML authentication exchange involves sending an SAML request to the Identity Provider (ADFS, Okta, etc...) and then receiving a signed SAML response. Both the request and the response will be transferred through POST HTTP requests made from the browser (other means of exchanging the data exist, but aren't supported by this library).
SamlClient client = SamlClient.fromMetadata("MyRelyingPartyIdentifier", "http://some/url/that/processes/assertions", "<your.IDP.metadata.xml>");
String encodedRequest = client.getSamlRequest(); String idpUrl = client.getIdentityProviderUrl(); // redirect to the identity provider, passing the encoded request with the SAMLRequest form parameter.
String encodedResponse = servletRequest.getParameter("SAMLResponse"); SamlResponse response = client.decodeAndValidateSamlResponse(encodedResponse); String authenticatedUser = response.getNameID();
String encodedRequest = getLogoutRequest(nameID); // redirect to the identity provider, passing the encoded request with the SAMLRequest form parameter.
//Allow to inform the IDP the state of the service provider logout String encodedRequest = getSamlLogoutResponse(statusCode, statusMessage); // redirect to the identity provider, passing the encoded request with the SAMLRequest form parameter.
// To initiate the authentication exchange client.redirectToIdentityProvider(servletResponse, null); ... // To process the POST containing the SAML response SamlResponse response = client.processPostFromIdentityProvider(servletRequest); ... // To process the POST containing the SAML Logout Request processLogoutRequestPostFromIdentityProvider(servletRequest,nameID) ... //To process the POST containing the SAML Logout Response processPostLogoutResponseFromIdentityProvider(servletRequest)
To configure ADFS to work with this library, you should go to the MMC snap-in for ADFS and add a Relying Party Trust with the following properties:
POSTfor the Binding value.
Then, to obtain the metadata provider XML, load this url in your browser: https://myserver.domain.com/FederationMetadata/2007-06/FederationMetadata.xml
To configure Okta to work with this library, create an SAML 2.0 application with the following settings:
To generate the public / private keys :
openssl req -new -x509 -days 365 -nodes -sha256 -out saml-public-key.crt -keyout saml-private-key.pem openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in saml-private-key.pem -out saml-private-key.key openssl pkcs8 -topk8 -nocrypt -inform PEM -in saml-private-key.key -outform DER -out saml-private-key.pk8
To add the keys :
// To add the keys (is needed only if you have encrypted assertion or if you want to sign documents) client.setSPKeys(publicKeyPath,privateKeyPath);