0
0
SpringbootHow-ToBeginner · 4 min read

How to Use Role Based Access in Spring Security

Use @EnableWebSecurity and configure HttpSecurity to restrict access by roles with .hasRole(). Annotate methods or controllers with @PreAuthorize or @Secured to enforce role-based access in Spring.
📐

Syntax

Spring Security uses configuration and annotations to control access based on user roles.

  • @EnableWebSecurity: Enables Spring Security in your app.
  • HttpSecurity: Configures URL access rules.
  • .hasRole('ROLE_NAME'): Restricts access to users with a specific role.
  • @PreAuthorize("hasRole('ROLE_NAME')"): Secures methods by role.
java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }
}
💻

Example

This example shows a Spring Boot app with role-based access: only users with role ADMIN can access /admin, and users with USER or ADMIN roles can access /user. The @PreAuthorize annotation secures a method by role.

java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class RoleBasedAccessApp {
    public static void main(String[] args) {
        SpringApplication.run(RoleBasedAccessApp.class, args);
    }
}

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }
}

@RestController
class MyController {

    @GetMapping("/admin/dashboard")
    public String adminDashboard() {
        return "Admin Dashboard - Access granted";
    }

    @GetMapping("/user/profile")
    @PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
    public String userProfile() {
        return "User Profile - Access granted";
    }
}
Output
When logged in as ADMIN user: Accessing /admin/dashboard returns "Admin Dashboard - Access granted" Accessing /user/profile returns "User Profile - Access granted" When logged in as USER user: Accessing /admin/dashboard returns 403 Forbidden Accessing /user/profile returns "User Profile - Access granted"
⚠️

Common Pitfalls

Common mistakes include:

  • Not enabling method security with @EnableGlobalMethodSecurity(prePostEnabled = true), so @PreAuthorize annotations are ignored.
  • Using .hasRole("ADMIN") but forgetting Spring Security adds ROLE_ prefix internally, so roles must be named like ROLE_ADMIN.
  • Not configuring authentication properly, so roles are not assigned to users.
  • Using @Secured without enabling securedEnabled = true in @EnableGlobalMethodSecurity.
java
/* Wrong: Missing @EnableGlobalMethodSecurity disables @PreAuthorize */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and().formLogin();
    }
}

/* Right: Enable method security */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and().formLogin();
    }
}
📊

Quick Reference

  • @EnableWebSecurity: Activate Spring Security.
  • HttpSecurity: Define URL access rules with .antMatchers() and .hasRole().
  • @EnableGlobalMethodSecurity(prePostEnabled = true): Enable method-level security.
  • @PreAuthorize("hasRole('ROLE')"): Secure methods by role.
  • Remember Spring Security prefixes roles with ROLE_ internally.

Key Takeaways

Enable Spring Security with @EnableWebSecurity and configure HttpSecurity for URL role restrictions.
Use @EnableGlobalMethodSecurity(prePostEnabled = true) to activate method-level role checks with @PreAuthorize.
Prefix roles with ROLE_ in your user details to match Spring Security's default role prefix.
Secure URLs and methods consistently to avoid unauthorized access.
Test with different user roles to verify access control works as expected.