Situation
Okta is a cloud-based SSO platform that allows users to enter one name and password to access multiple applications. It also works as an identity provider, which is useful if you want to store credentials outside your service.
There are two user groups where SSO integration makes sense: business users and customers.
Complexity
Hybris OOTB doesn’t support any particular SSO providers. It has a module named samlsinglesignon, which can be used for integration with any SAML-compatible SSO service. However, this module is designed only for hybris Assisted Service Module functionality and belongs to the call center features.
Solution
The video below shows the results of this experiment.
In the video, Okta is an external identity provider: hybris login → “OKTA” button → OKTA.com form → Okta credentials → hybris e-shop, where the customer is authenticated.
Technical solution
Behind the scenes, the interaction between Okta and hybris looks like this:
- Once you try to access the protected resource, the system redirects you to the SSO entry point: the
samlsinglesignonextension,/saml/. - The SSO entry point generates a new authentication request using the SAML 2.0 protocol, digitally signs it, and sends it to Okta.
- After authentication at Okta with your account, you will be redirected back to hybris and automatically signed in.
- The
samlsinglesignonextension listens to incoming requests (/samlsinglesignon/*). Once the extension receives a request from Okta, it checks whether the request has a correct SAML assertion. If it fails, the extension redirects the user back to the identity provider, Okta, and the user is asked to log in. - Otherwise, it creates the secure cookie samlPassThroughToken and redirects the user to the URL of the protected resource. This cookie should be used to initiate the customer session by the website. The SSO functionality in hybris is preconfigured to work with the ASM module, so there is an asmaddon that has a filter that processes samlPassThroughToken and sets a session user if the token is found. We are not going to use ASM Addon in this solution, so we need to write our own processor that sets up the customer session based on the cookie from samlsinglesignon.

There are a number of edge cases that need to be supported in your code. For example, the IDP session may end earlier or later than the storefront session. In the “later” case, the storefront should request the token again and re-establish authentication seamlessly without any data loss. You don’t need to parse the token and authenticate the user if this user has already been authenticated. You also need to support single sign-out. User data provisioning is also needed if you use Okta as the IDP. If you use the external IDP for more than one customer type, you need to support different types of sessions.
Configuring Okta
- Request a developer account (trial) from okta.com.
- Create an app in the Okta console. In my case, it is “electronics.local”.

Create new app → SAML 2.0 → enter the app name, then specify two URLs:
Single Sign on URL. Change your domain here: https://localhost:9002/samlsinglesignon/saml/SSO. It is very important to specify the correct domain and protocol here.
Audience URI (SP Entity ID): urn:ssoextension:hybris:de or your own SP Entity ID. You can change it in the configuration. I used the default value.
Download the certificate here:

Download
metadata.xmlusing the “Identity Provider metadata” link:
You will need to re-download it each time you change app settings. You need to restart hybris each time you replace
metadata.xml.Create a sample user:

Assign the app to the user. This operation could be done automatically later using the API, if needed.
Configuring the samlsinglesignon extension
- Create a JKS file. The simplest way is to use the default keystore file included in the extension. The right way is to create it from scratch; see the
keytooldocumentation.
keytool.exe -certreq -alias hybris -keystore samlKeystore.jks -file certificate.cerCopy the downloaded metadata.xml into the security folder, or change sso.metadata.location to your own. Change the following parameters. I used the default values.
sso.metadata.location = classpath:security/metadata.xml
sso.entity.id = urn:ssoextension:hybris:de
sso.keystore.location = security/samlKeystore.jks
sso.keystore.password = changeit
sso.keystore.privatekey.password = changeit
sso.keystore.default.certificate.alias = hybris
sso.keystore.privatekey.alias = hybrisToken processor
For ASM, you don’t need to do anything: token processing has already been implemented in AssistedServiceFilter.java:
protected void doFilterInternal(final HttpServletRequest httpservletrequest, final HttpServletResponse httpservletresponse,
final FilterChain filterchain) throws ServletException, IOException
{
if (AssistedServiceUtils.getSamlCookie(httpservletrequest) != null)
{
try
{
final LoginToken token = new CookieBasedLoginToken(AssistedServiceUtils.getSamlCookie(httpservletrequest));
// perform login only in case token doesn't belong to currently logged in agent
if (!getAssistedServiceFacade().isAssistedServiceAgentLoggedIn()
|| !getAssistedServiceFacade().getAsmSession().getAgent().getUid().equals(token.getUser().getUid()))
{
if (getAssistedServiceFacade().isAssistedServiceAgentLoggedIn())
{
getAssistedServiceFacade().logoutAssistedServiceAgent();
}
getAssistedServiceFacade().loginAssistedServiceAgent(httpservletrequest);
getAssistedServiceAgentLoginStrategy().login(token.getUser().getUid(), httpservletrequest, httpservletresponse);
getAssistedServiceFacade().emulateAfterLogin();
}
}
...For customers and cockpit administrators, you need to set the session manually:
....
final UserModel user = userService.getUserForUID(token.getUser().getUid());
....Create a filter in the storefront extension that will check whether the cookie is created and start the session by getting the user from the cookie.

Note: This filter should be defined last in the storefront filter chain, or after springSecurityFilterChain, so that it gets called after jsessionid is created.
© Rauf Aliev, June 2016