NF11 Single SignOn

From iDempiere en

Feature: Single Sign-On

Goal: Security

Developer: Logilite Technologies

Goal

iDempiere 11 has added support for single sign-On. Single sign-on on help to get authenticated with third party identity provider like Azure MSAL or AWS cognito server. This make requirement to store credentials of employee in database and make more secure against threat exposing user data.

iDempiere provides services to implement plugin for any SSO providers. The goal of this How-To is to show how to develop plug-in project to support new SSO. For creating blank plugin project, refer guide as Get Your Plugins Running

logilite has developed and made available plugins for MSAL (Azure) and AWS Cognito.

Not implemented yet

The current version of SSO does not implement changes on: - SOAP and REST web services, these keep working with AD_User authentication - SSO provider per tenant is not implemented, this would require a mechanism to identify the tenant on the URL

How to Enable SSO

Deepak Pansheriya has published plugins for Azure and Cognito, you can start using it with these plugins:

You can find instructions about how to configure AWS Cognito and the plugin within iDempiere in the provided file:

AmazonCognitoConfiguration.docx

How to implement SSO

Adding new item in SSO Provider drop down

On SSO configuaraion screen has SSO Provider field which list all SSO provider implementations available as plugin. first step is to add your SSO provider name in this drop down. For same follow below steps.

  • If you are adding new identity provider support, first step is to add SSO (identity) Provider Name in SSO Provider List on Reference.
  • For same login as System user in system tenant.
  • Open Reference window and locate record with name "SSO Provider List"
  • Next go to tab list validation and create new entry
  • Provide unique search key and name. Search key is used in your factory to identify configured SSO for your implementation

Adding dependencies in your plugin

  • open MANIFEST.MF of your plugin project and on dependency tab under required plugins, add following plugin dependencies as shown below
  1. org.adempiere.base
  2. org.eclipse.jetty.servlet-api
  3. org.adempiere.plugin.utils

Implementing SSO Factory

For implementing SSO factory, add new class implementing ISSOPrincipleFactory as below. you should add condition in which case the object of your SSO provider (ISSOPrinciple) implementor should be returned. Mostly we used SSO Provider configured on sso configuration screen.

 1import org.adempiere.base.sso.ISSOPrinciple;
 2import org.adempiere.base.sso.ISSOPrincipleFactory;
 3import org.compiere.model.I_SSO_PrincipleConfig;
 4
 5import com.logilite.sso.test.principle.MSSOPrinciple;
 6
 7public class MySSOFactory implements ISSOPrincipleFactory
 8{
 9	@Override
10	public ISSOPrinciple getSSOPrincipleService(I_SSO_PrincipleConfig config)
11	{
12		if ("MYSSOPROVIDER".equalsIgnoreCase(config.getSSO_Provider()))
13			return new MSSOPrinciple(config);
14		return null;
15	}
16}

Implement SSO Provider

SSO Provider class implements ISSOPrinciple interface.

ISSOPrinciple Method:

hasAuthenticationCode
  • Method has request (HttpServletRequest) , response (HttpServletResponse) as a parameter.
  • Method will return true, if a request has an authentication code from SSO provider, other wise false.
getAuthenticationToken
  • Method has request (HttpServletRequest) , response (HttpServletResponse) and redirectMode (String) as a parameter.
  • Method will send a request to SSO provider with the code & redirect URL to get the auth token & and save token in session.
  • Token is save in session with attribute name SSOPrinciple.SSO_PRINCIPLE_SESSION_NAME.
isAuthenticated
  • Method has request (HttpServletRequest) , response (HttpServletResponse) as a parameter.
  • Method will return true, if session has auth token, other wise false.
redirectForAuthentication
  • Method has request (HttpServletRequest) , response (HttpServletResponse) and redirectMode (String) as a parameter.
  • Method will redirect request to the SSO provider for authentication.
removePrincipleFromSession
  • Method has request (HttpServletRequest) , response (HttpServletResponse) as a parameter.
  • Method will remove auth token from session.
getUserName
  • Method has result (Object) as a parameter, result is token save in session.
  • Method will return user name/email from token, as per System Configurator USE_EMAIL_FOR_LOGIN.
getLanguage
  • Method has result (Object) as a parameter, result is token save in session.
  • Method will return Login Language from token.

SSOUtils Method:

getRedirectedURL
  • Method take redirectMode (String) , config (I_SSO_PrincipleConfig) as a parameter.
  • Method will return Redirect URIs (String) from SSO Provider configured (config) as per redirectMode .
  • We have Redirect Mode as below.
    1. SSOUtils.SSO_MODE_OSGI - Apache Felix Web Console Bundles
    2. SSOUtils.SSO_MODE_MONITOR - iDempiere Monitor
    3. SSOUtils.SSO_MODE_WEBUI - Web login
  1import java.io.IOException;
  2import java.text.ParseException;
  3
  4import javax.servlet.http.HttpServletRequest;
  5import javax.servlet.http.HttpServletResponse;
  6
  7import org.adempiere.base.sso.ISSOPrinciple;
  8import org.adempiere.base.sso.SSOUtils;
  9import org.compiere.model.I_SSO_PrincipleConfig;
 10import org.compiere.model.MSysConfig;
 11import org.compiere.util.Language;
 12
 13/**
 14 * in core {@link #BridgeFilter}, {@link #AdempiereMonitorFilter}, {@link #SSOWebuiFilter} filter
 15 * use ISSOPrinciple methods to log-in/authenticated users using the SSO provider.
 16 */
 17public class MSSOPrinciple implements ISSOPrinciple
 18{
 19
 20	private I_SSO_PrincipleConfig config;
 21
 22	public MSSOPrinciple(I_SSO_PrincipleConfig ssoConfig)
 23	{
 24		setConfig(ssoConfig);
 25	}
 26
 27	/**
 28	 * When a request comes to any filter class, a request is checked for
 29	 * authentication code from the SSO provider.
 30	 */
 31	@Override
 32	public boolean hasAuthenticationCode(HttpServletRequest request, HttpServletResponse response)
 33	{
 34		// Check request has authentication code
 35		return false;
 36	}
 37
 38	/**
 39	 * if {@code #hasAuthenticationCode(HttpServletRequest, HttpServletResponse)} returns true, then
 40	 * request is sent to the SSO provider with the code & response redirect URL to get the
 41	 * authenticated user token & and saved token in the session attribute
 42	 * {@link #ISSOPrinciple.SSO_PRINCIPLE_SESSION_NAME}
 43	 */
 44	@Override
 45	public void getAuthenticationToken(HttpServletRequest request, HttpServletResponse response, String redirectMode) throws Throwable
 46	{
 47		/**
 48		 * we have three redirectMode
 49		 * 1. SSOUtils.SSO_MODE_OSGI - Apache Felix Web Console Bundles
 50		 * 2. SSOUtils.SSO_MODE_MONITOR - iDempiere Monitor
 51		 * 3. SSOUtils.SSO_MODE_WEBUI - Web login
 52		 */
 53		// get redirect URL for SSO.
 54		String sso_Redirect_URL = SSOUtils.getRedirectedURL(redirectMode, getConfig());
 55		// SSO authentication token code
 56
 57		// request.getSession().setAttribute(ISSOPrinciple.SSO_PRINCIPLE_SESSION_NAME, token);
 58	}
 59
 60	/**
 61	 * if {@code #hasAuthenticationCode(HttpServletRequest, HttpServletResponse)} returns false,
 62	 * then current session attribute {@link #ISSOPrinciple.SSO_PRINCIPLE_SESSION_NAME}
 63	 * have a token or not.
 64	 */
 65	@Override
 66	public boolean isAuthenticated(HttpServletRequest request, HttpServletResponse response)
 67	{
 68		// Check request session is authenticated
 69		return false;
 70	}
 71
 72	/**
 73	 * if {@code #isAuthenticated(HttpServletRequest, HttpServletResponse)} returns false,
 74	 * then the current request is redirected to the SSO provider for login/authentication.
 75	 */
 76	@Override
 77	public void redirectForAuthentication(HttpServletRequest request, HttpServletResponse response, String redirectMode) throws IOException
 78	{
 79		// Code for redirect to SSO provider
 80	}
 81
 82	/**
 83	 * If there is any error SSO login/authenticating we remove the token and other save data from the
 84	 * request session.
 85	 */
 86	@Override
 87	public void removePrincipleFromSession(HttpServletRequest httpRequest)
 88	{
 89		// code to remove a token from the session or other info saved during SSO login.
 90	}
 91
 92	/**
 93	 * return authenticate user name/email from token to validate in iDempiere
 94	 */
 95	@Override
 96	public String getUserName(Object result) throws ParseException
 97	{
 98		// check if IDempiere login validate by email/user name
 99		boolean isEmailLogin = MSysConfig.getBooleanValue(MSysConfig.USE_EMAIL_FOR_LOGIN, false);
100		// Return the login user name/email.
101		return null;
102	}
103
104	/**
105	 * return {@link #Language} for login user, can be changed from Role panel
106	 */
107	@Override
108	public Language getLanguage(Object result) throws ParseException
109	{
110		// Return login language/user IDempiere default method Language.getBaseLanguage();
111		return null;
112	}
113
114	public I_SSO_PrincipleConfig getConfig()
115	{
116		return config;
117	}
118
119	public void setConfig(I_SSO_PrincipleConfig config)
120	{
121		this.config = config;
122	}
123}

Create Component Definition

  • Create OSGI-INF Folder in plugin if does not exist
  • Right click in OSGI-INF > New > Other..
OSGI-INF Folder.png

Open Wizard.png

  • Search Component Definition
  • Click Next
  • Enter Class, Name and File name as shown in image below
  • Click Finish
Component Definition Wizard.png

NewComponentDefinition.png

  • Click Add Property with below details
    • Name: service.ranking
    • Type: Integer
    • Values: 10
Service.ranking.png

Service.ranking img.png

  • Select Services section
  • Provide Services > click Add
  • Search ISSOPrincipleFactory
  • Click OK
Service ISSOPrincipleFactory.png

Services ISSOPrincipleFactory Img.png

  • Component Definition myssofactory.xml look as below
1<?xml version="1.0" encoding="UTF-8"?>
2<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="com.logilite.sso.test.factory.MySSOFactory">
3   <implementation class="com.logilite.sso.test.factory.MySSOFactory"/>
4   <property name="service.ranking" type="Integer" value="10"/>
5   <service>
6      <provide interface="org.adempiere.base.sso.ISSOPrincipleFactory"/>
7   </service>
8</scr:component>

Configuring Single Sign-On (SSO) in iDempiere

1. Log in as System User

   - Access to system-wide configurations is typically limited to users with System-level privileges.

2. SSO Configuration

   - This step involves setting up the connection between iDempiere and the chosen SSO provider.

   - The configuration details include essential information like Tenant ID, Application Client ID, and Secret Key. These details allow iDempiere to communicate securely with the SSO provider.

   - Redirect URIs are specified to ensure that the authentication process is seamless and secure.

   - Marking a configuration as "Default" designates it as the primary SSO configuration, ensuring that it is used for SSO logins.

3. Enabling SSO for WebUI

   - Once the SSO configurations are set up, the system-wide switch for enabling or disabling SSO for WebUI is controlled through the `ENABLE_SSO` System Configurator parameter.

   - Setting `Configured Value` to Y activates SSO login functionality for WebUI, while N reverts to the standard iDempiere login page.

4. Enabling SSO for iDempiere Monitor

   - A specific System Configurator parameter, `ENABLE_SSO_IDEMPIERE_MONITOR`, allows enabling or disabling SSO specifically for iDempiere Monitor.

5. Enabling SSO for Felix Web Console

   - The `ENABLE_SSO_OSGI_CONSOLE` System Configurator parameter serves the same purpose but for Felix Web Console.

6. Using Email for Login Validation (Optional)

   - This configuration, controlled by the `USE_EMAIL_FOR_LOGIN` parameter, provides flexibility in the login process. When enabled, users can log in using their email addresses instead of display names.

7. Role Selection when Logging in with SSO (Optional)

   - The `SSO_SELECT_ROLE` parameter influences the login experience further. When enabled, users logging in through SSO are presented with a Role Panel, allowing them to select a specific role if applicable.


Technical Info: IDEMPIERE-5346

See also

Cookies help us deliver our services. By using our services, you agree to our use of cookies.