Method Level Security in Spring Boot: How to Use It
To use
method level security in Spring Boot, enable it by adding @EnableMethodSecurity to your configuration class. Then, secure methods by annotating them with security annotations like @PreAuthorize or @PostAuthorize to control access based on roles or permissions.Syntax
Enable method level security by adding @EnableMethodSecurity on a configuration class. Use annotations like @PreAuthorize before methods to specify access rules.
@EnableMethodSecurity: Activates method security processing.@PreAuthorize("expression"): Checks the expression before method execution.@PostAuthorize("expression"): Checks the expression after method execution.@Secured({"ROLE_NAME"}): Specifies roles allowed to invoke the method.
java
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; @Configuration @EnableMethodSecurity public class SecurityConfig { // Security configuration here } // Example usage in a service import org.springframework.security.access.prepost.PreAuthorize; public class MyService { @PreAuthorize("hasRole('ADMIN')") public void adminOnlyMethod() { // method logic } @PreAuthorize("hasAuthority('read')") public void readMethod() { // method logic } }
Example
This example shows a Spring Boot application with method level security enabled. The adminOnlyMethod can only be called by users with the ADMIN role.
java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.context.annotation.Bean; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Configuration @EnableMethodSecurity static class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .httpBasic(); return http.build(); } @Bean public UserDetailsService users() { UserDetails user = User.builder() .username("user") .password(passwordEncoder().encode("password")) .roles("USER") .build(); UserDetails admin = User.builder() .username("admin") .password(passwordEncoder().encode("password")) .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } @Service public static class MyService { @PreAuthorize("hasRole('ADMIN')") public String adminOnlyMethod() { return "Access granted to admin method."; } @PreAuthorize("hasRole('USER')") public String userMethod() { return "Access granted to user method."; } } }
Output
When logged in as 'admin' and calling adminOnlyMethod(): "Access granted to admin method."
When logged in as 'user' and calling adminOnlyMethod(): Access denied error
Common Pitfalls
- Forgetting to add
@EnableMethodSecuritydisables method security annotations. - Using
@PreAuthorizewithout enablingprePostEnabledin older Spring versions (before 6.0). - Not matching roles exactly, e.g.,
hasRole('ADMIN')expects role name withoutROLE_prefix. - Trying to secure private methods; Spring proxies only public methods by default.
java
/* Wrong: Missing @EnableMethodSecurity disables method security */ @Configuration public class SecurityConfig { // no method security enabled } /* Right: Enable method security */ @Configuration @EnableMethodSecurity public class SecurityConfig { // method security enabled }
Quick Reference
Use this quick reference to remember key annotations and their purpose:
| Annotation | Purpose |
|---|---|
| @EnableMethodSecurity | Enables method level security processing |
| @PreAuthorize("expression") | Checks authorization before method execution |
| @PostAuthorize("expression") | Checks authorization after method execution |
| @Secured({"ROLE_NAME"}) | Restricts method access to specified roles |
| @RolesAllowed({"ROLE_NAME"}) | Java EE standard for role-based access control |
Key Takeaways
Add @EnableMethodSecurity to your configuration to activate method level security.
Use @PreAuthorize to restrict method access based on roles or permissions.
Roles in hasRole() should be specified without the ROLE_ prefix.
Method security works on public methods by default due to Spring proxies.
Test security by logging in with different users and calling secured methods.