Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring - Add Roles in Spring Security

Spring Security provides a robust framework for securing your applications. Roles (also known as authorities) are one of the core concepts in Spring Security. They represent the privileges assigned to authenticated users.

Here's a step-by-step guide to set up and use roles in a Spring application:

1. Set up Spring Security dependencies:

Ensure you have the required dependencies in your pom.xml:

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. Configure Spring Security:

You can configure Spring Security by extending WebSecurityConfigurerAdapter:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")  // Only allow users with ADMIN role to access /admin/** endpoints
                .antMatchers("/user/**").hasRole("USER")    // Only allow users with USER role to access /user/** endpoints
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password(passwordEncoder().encode("password")).roles("USER")
                .and()
                .withUser("admin").password(passwordEncoder().encode("adminpassword")).roles("ADMIN");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

In this example, I used an in-memory authentication mechanism to set up a user with the "USER" role and an admin with the "ADMIN" role. In a real-world application, you'll likely use a database or another storage mechanism.

3. Use @PreAuthorize or @Secured annotations:

Spring Security provides annotations to secure methods directly based on roles.

First, enable method security by adding @EnableGlobalMethodSecurity:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // ... other configurations
}

Then, use annotations in your services or controllers:

@Service
public class MyService {

    @PreAuthorize("hasRole('ADMIN')")
    public void adminOnlyMethod() {
        // Only admin can execute this
    }

    @Secured("ROLE_USER")
    public void userMethod() {
        // Only user can execute this
    }
}

Note: @PreAuthorize uses the SpEL syntax and provides more flexibility, whereas @Secured is straightforward and expects prefixed role names.

4. Get the roles of the currently logged-in user:

You can obtain the roles of the currently logged-in user through the SecurityContextHolder:

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

// ...

public boolean isAdmin() {
    return SecurityContextHolder.getContext().getAuthentication().getAuthorities()
        .contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
}

In summary, roles are fundamental in Spring Security for determining what authenticated users are allowed to do. They can be applied at the web layer (for URLs) and the method layer (for service methods). Adjustments can be made to cater to more complex scenarios, such as custom role hierarchies or database-backed user and role storage.

  1. Spring Security add roles to user:

    • Adding roles to a user involves defining roles and assigning them to the user's authentication details.
    public class CustomUserDetailsService implements UserDetailsService {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // Fetch user details from your data source
            User user = // ... retrieve user details
    
            // Assign roles to the user
            List<GrantedAuthority> authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
    
            return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                authorities
            );
        }
    }
    
  2. Configuring roles in Spring Security:

    • Configure roles in the security configuration file.
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .httpBasic();
        }
    
        // Other configurations...
    }
    
  3. Granting roles to users in Spring Security:

    • Grant roles to users based on their authentication.
    public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
        @Override
        public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication
        ) throws IOException {
            // Grant roles to the user
            // ...
            response.sendRedirect("/home");
        }
    }
    
  4. Role-based authentication in Spring Security:

    • Authenticate users based on their assigned roles.
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic();
    }
    
  5. How to assign roles to users in Spring Security:

    • Assign roles during user authentication.
    public class CustomUserDetailsService implements UserDetailsService {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // Fetch user details from your data source
            User user = // ... retrieve user details
    
            // Assign roles based on user attributes or conditions
            List<GrantedAuthority> authorities = new ArrayList<>();
            if (user.isAdmin()) {
                authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            }
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
    
            return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                authorities
            );
        }
    }
    
  6. Customizing user roles in Spring Security:

    • Customize user roles based on your application's requirements.
    public class CustomUserDetailsService implements UserDetailsService {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // Fetch user details from your data source
            User user = // ... retrieve user details
    
            // Customize roles based on business logic
            List<GrantedAuthority> authorities = customRoleLogic(user);
    
            return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                authorities
            );
        }
    
        private List<GrantedAuthority> customRoleLogic(User user) {
            // Custom logic to determine roles
            // ...
            return authorities;
        }
    }
    
  7. Defining roles and permissions in Spring Security:

    • Define roles and permissions in your application.
    public class MyPermissionEvaluator implements PermissionEvaluator {
        @Override
        public boolean hasPermission(
            Authentication authentication,
            Object targetDomainObject,
            Object permission
        ) {
            // Check if the user has the required permission for the target object
            // ...
            return hasPermission;
        }
    }
    
  8. Securing Spring application with roles in Spring Security:

    • Secure your application by configuring role-based access.
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .httpBasic();
    }
    
  9. Managing user roles with Spring Security:

    • Manage user roles through the UserDetailsService and configure security rules accordingly.
    public class CustomUserDetailsService implements UserDetailsService {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // Fetch user details from your data source
            User user = // ... retrieve user details
    
            // Manage roles based on your application's requirements
            List<GrantedAuthority> authorities = manageRoles(user);
    
            return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                authorities
            );
        }
    
        private List<GrantedAuthority> manageRoles(User user) {
            // Manage roles based on business logic
            // ...
            return authorities;
        }
    }