Saturday, May 11, 2024

Role based Access control using Spring Security and MVC, Mapping LDAP Groups to Authorities for Authorization

Authentication and Authorization is an integral part of any Java enterprise or web application. Since most of the company uses LDAP Active directory for authentication, authorization, and Role-based access control (RBAC), it's good to know How to implement Role-based access control using Spring MVC and Spring Security. This is the second part of my articles on using Spring Security for authentication and authorization in Spring MVC based Java application. In the last part, we have learned about doing LDAP authentication against Windows active directory, and in this Spring Security tutorial, we will learn How to map LDAP groups to authorities for implementing Role-based access control or authorization.

If you are developing an application, whose access is controlled by adding a user to a particular LDAP group, then you need a mechanism to load those LDAP group after successful authentication. Spring Security uses GrantedAuthority class for holding all roles for a particular user. 

Based on these roles, a particular user can perform certain functionality in your application. For example, a read-only user can only see data, but a user with an ADMIN role can add or remove data from your application. 

After implementing Role-based access control, you are free of user management tasks, those will be taken care of by the respective team which manages LDAP groups and access, usually Windows support teams. 

In this article, we will all the steps required to map LDAP groups to granted authorities in Spring Security.  If you are developing a secure enterprise application in Java and considering spring-security, this is one of the best online course on Spring Security. 


Steps to Map LDAP groups to Authorities for Role-based Access Control (RBAC)


1) Create an Application-specific Authority classes, usually an enum with values like APP_USER, APP_ADMIN

2) Create Authority Mapper which will Map LDAP groups to application-specific authority for example if the group in LDAP is "Application Access (Gn)" then mapping that to APP_USER.

3) If you are authenticating against the Active directory then provide your custom Authority mapper to ActiveDirectoryLdapAuthenticationProvider. After successful authentication, it will load all the groups for which authenticated user_id is a member, and map with application-specific authority.

4) Use application-specific authorities or roles as APP_USER or APP_ADMIN to secure your URL's by using

<intercept-url pattern="/secure/admin/**" access="hasRole('APP_ADMIN')"/>
 
<intercept-url pattern="/secure/user/**" access="hasRole('APP_USER')"/>
<intercept-url pattern="/secure/**" access="isAuthenticated()" />





Java code for Mapping LDAP Groups to Authorities using Spring Security

Here is the Java code, required to map LDAP groups into granted authorities of Spring Security. We need one class, usually enum to create roles supported by our application, this must implement the GrantedAuthority interface, which is used to represent a role in Spring Security. 

Now we need a Mapper class to map LDAP groups into granted authorities, this class must implement the GrantedAuthoritiesMapper interface. 

We create an instance of this class using Spring and provide names of LDAP groups for mapping with a particular role. 

For example, if the application has two roles USER and ADMIN and LDAP group "Application User Access (Gn)" is for User and "Application Admin Access (Gn)" is for Admin, then this information is configured in Spring configuration file and this authority mapper is provided to LDAP authentication provider. 

Keeping the application role separate from LDAP groups allows you to cope up with any change in the LDAP group name, you just need to change your spring configuration file.

Role based Access control using Spring Security and MVC, Mapping LDAP Groups to Authorities for Authorization



LDAPGrantedAuthoritiesMapper.java

import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
 
/**
 * LDAP Authorities mapper, Maps LDAP groups to APP_USER and APP_ADMIN
 */
public class LDAPGrantedAuthoritiesMapper implements GrantedAuthoritiesMapper {
    private final String APP_USER ="Ldap User Group";   //default user ldap group
    private final String APP_ADMIN ="Ldap Admin Group"; //default adming ldap group
 
    public ADGrantedAuthoritiesMapper(String userGroup, String adminGroup) {
        APP_USER = userGroup;
        APP_ADMIN = adminGroup;
 
    }
 
    public Collection  mapAuthorities(
            final Collection authorities) {
 
        Set roles = EnumSet.noneOf(LDAPAuthority.class); //empty EnumSet
 
        for (GrantedAuthority authority : authorities) {
            if (APP_USER.equals(authority.getAuthority())) {
                roles.add(LDAPAuthority.APP_USER);
            } else if (APP_ADMIN.equals(authority.getAuthority())) {
                roles.add(LDAPAuthority.APP_ADMIN);
            }
        }
        return roles;
    }
}

LDAPAuthority.java

import org.springframework.security.core.GrantedAuthority;
 
/**
 * Maps LDAP Group application roles
 */
public enum LDAPAuthority implements GrantedAuthority{
    APP_USER, APP_ADMIN; //roles used in application
   
    public String getAuthority() {
        return name();
    }
   
}

Spring Security Configuration for Role-based Access and Mapping LDAP groups

Mapping LDAP authorities into role based access Java spring security exampleAs stated above, the first configuration is creating an instance of LDAPGrantedAuthoritiesMapper and mapping LDAP groups to application roles, so that when a user is successfully authenticated and comes with all LDAP groups, he is member of, those groups are read and converted into corresponding roles. 

The second configuration is to provide this mapper to ActiveDirectoryLdapAuthenticationProvider, this is similar to our last example of LDAP authentication, except <beans:property name="authoritiesMapper" ref="ldapAuthoritiesMapper"/>, which is requite to map LDAP groups to granted authorities for role-based access control.



<beans:bean id="ldapAuthoritiesMapper" 
    class="com.abc.web.security.LDAPGrantedAuthoritiesMapper">
        <beans:constructor-arg value="Ldap User Group" />
        <beans:constructor-arg value="Ldap Admin Group" />
</beans:bean>   
 
<beans:bean id="LdapAuthProvider"  
class="org.springframework.security.ldap.authentication.ad.
                                  ActiveDirectoryLdapAuthenticationProvider">
        <beans:constructor-arg ref="domain" />
        <beans:constructor-arg ref="url" />
        <beans:property name="convertSubErrorCodesToExceptions" value="true"/>
        //LDAP authority mapper
        <beans:property name="authoritiesMapper" ref="ldapAuthoritiesMapper"/>   
        
        <beans:property name="useAuthenticationRequestCredentials" value="true"/>
</beans:bean
 

That's all you need to implement Role-based access control on your Spring MVC, Spring Security based Java web application. Like other features, LDAP authorization doesn't come out of the box from Spring Security and you need to follow the above steps to map LDAP groups to granted authorities.


Other Spring tutorials from Javarevisited Blog
  • Top 5 Courses to learn Spring in depth (courses)
  • 10 Exmaple of JdbcTemplate in Java? (JdbcTemplate Example)
  • Top 5 Spring Boot Features Java developer should know (features)
  • How to Solve java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener in Spring? [solution
  • 15 Spring Boot Interview Questions with Answers (questions)
  • How to Consume JSON from RESTful Web Service and Convert to Java Object? [Spring RestTemplate Example
  • 10 Free Courses to learn Spring Boot for Beginners (free courses)
  • 21+ Spring MVC Interview Questions for Java developers (Questions)
  • Top 5 Courses to learn Microservices in Java (courses)
  • 5 Best Resources for Spring Certification (resources)
  • How to Crack Spring Certification for Java developers (certification)
  • 10 Advanced Spring Boot Courses for Java developers (courses)
  • How to get a ServletContext object in the Spring controller? (example)
  • Top 5 Courses to learn Spring Boot in-depth (courses)
  • How to change the port of tomcat in Spring boot (tutorial)
  • Top 5 Books to learn Spring Boot and Spring Cloud (books)
  • What is the default bean scope in the Spring MVC framework? (answer)
  • Top 5 Courses to learn Spring Cloud for Java developers (courses)

4 comments:

  1. The name of this article should be changed to 'Using Roles for Access Control in Spring' rather than what it is currently called. Role-Based Access Control refers to ANSI RBAC INCITS 359 which uses roles in concert with permissions - and sessions. Binding roles directly to pages as you have done here is actually an anti-pattern for policy enforcement. The policy enforcement point should use always bind to permissions and let the access control mechanism determine what roles are needed.

    ReplyDelete
  2. I am also beginer
    i have one problem i e i want to give access to different user by folderwise
    so how i can do this

    ReplyDelete
  3. Understood how the roles are mapped to group names and how the authorities identified , now how these are roles linked security layer so that roles can be accessed to validate resources

    ReplyDelete
  4. Have idea about USER PROVISINING in Spring SAML application ?

    ReplyDelete