Custom implementation

While using SAML SSO to log in to the system, the SAML response can be interpreted to change the default behavior to make the user log in to a specific company/partner in a specific role. Adeptia Connect allows you to do this by implementing a custom class to read and authenticate the user information. To achieve this, you need to define a new Java class and place that in the customClasses folder.

This option lets you:

  • Access custom attributes and relay state information present in the SAML response
  • Provide a specific company/partner and also a specific role for logged in user
  • Provide a redirect URL to which user will be redirected after successful login

Follow the steps below to create the custom class:

  1. Create a new Java class that implements the below interface.

    This interface provides the ability to define a custom implementation for providing the authenticated user information.
     SAML SSO Authentication Interface
    SAML SSO Authentication Interface
    package com.adeptia.indigo.security.saml;
    
    import java.util.Map;
    
    import org.springframework.security.core.Authentication;
    
    /**
     * This interface provides the ability to define a custom implementation for
     * providing the authenticated user information.
     * 
     * The contract accepts the Authentication Object as an input which contains all
     * the information of authenticated user received as a part of SAML response.
     * The output delivered is the User's attributes and Target URL.
     * 
     * @author Ranjit
     *
     */
    public interface SAMLSSOAuthenticationUserDetails {
    
    	/**
    	 * Prepare the {@link SubjectInfo} for the authenticated User
    	 * 
    	 * @param authentication
    	 *            Represents the token for an authentication request or for an
    	 *            authenticated principal
    	 * 
    	 * @return The authenticated Subject attributes : user, Group, associated
    	 *         partner and associated role
    	 * 
    	 */
    	public SubjectInfo getSubjectInfo(Authentication authentication);
    
    	/**
    	 * The URL the SP should redirect the user once the SSO completes.
    	 * 
    	 * Generally the relay state present into SAML message specify the URL to which
    	 * the user is to be redirected.
    	 * 
    	 * @param authentication
    	 *            Represents the token for an authentication request or for an
    	 *            authenticated principal
    	 * 
    	 * @return the relative URL fragment identifier( value after hash #) or the
    	 *         complete absolute URL. The value assumed to be absolute URL if it
    	 *         starts with http:// or https://, otherwise the value is considered as
    	 *         Fragment identifier.
    	 */
    	public String getRedirectUrl(Authentication authentication);
    
    	/**
    	 * The user attributes received as a part of SAML assertions.
    	 * 
    	 * The user attributes Map to be returned should have Keys in String format and
    	 * values as Serializable objects.
    	 * 
    	 * @param authentication
    	 *            Represents the token for an authentication request or for an
    	 *            authenticated principal
    	 * 
    	 * @return the user attributes Map
    	 */
    	public Map<String, String> getAttributes(Authentication authentication);
    
    }
  2. Annotate the custom class with @Component, and @Scope annotations. 
    1. Provide the name of the component, for example, "SAMLUserDetailsImpl", as the value for Component annotation, and "prototype" as the value for Scope annotation.
    2. Put a constructor in this class. 

    Expand 'SAML User Details IMPL' for an example of implementation class: 

     SAML user details IMPL
    SAML User Details IMPL
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.opensaml.saml2.core.Attribute;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.saml.SAMLCredential;
    
    import com.adeptia.indigo.security.AuthUtil;
    import com.adeptia.indigo.security.IndigoGroup;
    import com.adeptia.indigo.security.IndigoUser;
    import com.adeptia.indigo.security.saml.SAMLSSOAuthenticationUserDetails;
    import com.adeptia.indigo.security.saml.SubjectInfo;
    
    @Component("SAMLUserDetailsImpl")
    @Scope("prototype")
    public class SAMLUserDetailsImpl implements SAMLSSOAuthenticationUserDetails{
    
    List<MappingField> userMappingList;
    
      public SAMLUserDetailsImpl(List<MappingField> userMappingList)
      {
        this.userMappingList = userMappingList;
      }
    
    	@SuppressWarnings("unchecked")
    	@Override
    	public SubjectInfo getSubjectInfo(Authentication authentication) {
    
    		SubjectInfo subjectInfo = new SubjectInfo();
    		subjectInfo.setUser(user);
    		subjectInfo.setGroupId(group);
    		subjectInfo.setPartner(partnerName);
    		subjectInfo.setRole(roleName);		
    		return subjectInfo;
    
    
    	}
    
    	@Override
    	public String getRedirectUrl(Authentication authentication) {
    		return "home";
    	}
    
    	@Override
    	public Map<String, String> getAttributes(Authentication authentication) {
    		SAMLCredential credential = (SAMLCredential) authentication.getCredentials();
    		Map<String, String> userAttributesMap = new HashMap<>();
    		userAttributesMap.put("RelayState", credential.getRelayState());
    		List<Attribute> userAttributes = credential.getAttributes();
    		for (Attribute attribute : userAttributes) {
    			String name = attribute.getName();
    			userAttributesMap.put(name, credential.getAttributeAsString(name));
    		}
    		return userAttributesMap;
    	}
    
    }
  3. Define the following environment variable in the portal section of the global values.yaml file to store the name of the implementation class (Name of the component).

    Variable NameValueDescription
    SAML_SSO_IMPLEMENTATION_BEANSAMLUserDetailsImplThis variable contains the name of the component.
  4. Compile the above class and place it in customClasses folder.
  5. Restart the Adeptia services to bring the changes into effect.