skip to content

What does @EnableMethodSecurity do, and what are its prePostEnabled, securedEnabled, and jsr250Enabled flags?

level: juniorimportance: must knowfreq 70%

answer

  1. @Configuration + @EnableMethodSecurity
  2. prePostEnabled defaults TRUE
  3. securedEnabled = @Secured (role list)
  4. jsr250Enabled = @RolesAllowed/@PermitAll/@DenyAll
  5. AOP proxy — self-invocation bypasses

basics

~10 s

@EnableMethodSecurity turns on security checks on individual methods (not just URLs). prePostEnabled activates @PreAuthorize/@PostAuthorize (on by default), securedEnabled activates @Secured, and jsr250Enabled activates @RolesAllowed. You put it on a @Configuration class.

solid answer

~40 s

@EnableMethodSecurity is the annotation (Spring Security 5.6+) you add to a @Configuration class to enable authorization on individual bean methods rather than only on HTTP requests. It registers AOP interceptors that evaluate security annotations before or after a method runs. Its three flags toggle which annotation families are active: prePostEnabled turns on Spring's @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter (and, importantly, it defaults to true); securedEnabled turns on the legacy role-list @Secured; jsr250Enabled turns on the JSR-250 annotations @RolesAllowed, @PermitAll, @DenyAll. You typically leave prePostEnabled on and only enable the others if your codebase uses those annotation styles. Method security is enforced through Spring AOP proxies, so calls must go through the proxy for the check to fire.

code

java · 16 lines
java
@Configuration
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
public class MethodSecurityConfig { }

@Service
public class AccountService {

    @PreAuthorize("hasRole('ADMIN')")            // prePostEnabled (default true)
    public void closeAccount(String id) { }

    @Secured("ROLE_ADMIN")                        // securedEnabled
    public void freeze(String id) { }

    @RolesAllowed("ADMIN")                        // jsr250Enabled
    public void reopen(String id) { }
}

go deeper

for a junior

Know it enables per-method checks and name the three flags with the annotations each turns on.

for a middle

Explain the defaults (prePostEnabled=true, others false) and that @PreAuthorize is SpEL while @Secured/@RolesAllowed are plain role lists.

for a senior

Explain the AOP-proxy enforcement path and the self-invocation gotcha, and advise which annotation family to standardize on.

for a principal

Discuss migration policy, meta-annotation/templated-expression support, and enabling multiple families safely across a large codebase.

## What it is `@EnableMethodSecurity` is a Spring Security annotation (introduced in **Spring Security 5.6**, GA in 5.8 / Spring Boot 3) that you place on a `@Configuration` class to enable **method-level authorization** — deciding whether a caller may invoke a specific bean method, as opposed to *web* authorization which guards HTTP request paths in the `SecurityFilterChain`. ```java @Configuration @EnableMethodSecurity // prePostEnabled = true by default public class MethodSecurityConfig { } ``` ## How it works under the hood When present, its `@Import(MethodSecuritySelector.class)` pulls in configuration that registers **Spring AOP advisors** (interceptor beans). Each secured bean is wrapped in a **proxy**; when a method annotated for security is called *through that proxy*, the matching interceptor runs an `AuthorizationManager` to grant or deny access, throwing `AccessDeniedException` on denial. ## The three flags - **prePostEnabled** — enables the Spring-native, SpEL-powered annotations: `@PreAuthorize` (check *before* the method), `@PostAuthorize` (check the *return value* after), `@PreFilter` (filter a collection/array *argument*), `@PostFilter` (filter the returned collection). **Unlike the old `@EnableGlobalMethodSecurity`, this flag defaults to `true`.** - **securedEnabled** — enables the legacy `@Secured` annotation, which takes a plain list of role strings, e.g. `@Secured("ROLE_ADMIN")`. No SpEL. Defaults to `false`. - **jsr250Enabled** — enables the Jakarta/JSR-250 standard annotations `@RolesAllowed("ADMIN")`, `@PermitAll`, `@DenyAll`. Defaults to `false`. ```java @EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) ``` ## Which to use Prefer `@PreAuthorize` (SpEL, can reference method arguments via `#name`, principal, authorities) for anything expressive. Use `@Secured` / `@RolesAllowed` only for simple role checks or to match an existing convention. You can enable more than one family simultaneously; different annotations then apply to different methods. ## Key gotchas - **Proxy self-invocation**: a call from one method of a bean to another method *of the same bean* (`this.other()`) bypasses the proxy, so its security annotation is **not** enforced. Route through an injected reference or split beans. - **Public methods only** by default (Spring AOP CGLIB/JDK proxies can't advise `private`/`final` methods the usual way). - Where you put the annotation still matters: it must be on a **Spring-managed bean**. - Meta-annotations / templated authorization expressions are supported (a big reason it replaced the old annotation).

  • If you only write @EnableMethodSecurity with no arguments, which annotations work?
    Only the pre/post family — @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter — because prePostEnabled defaults to true while securedEnabled and jsr250Enabled default to false.
  • Why might a @PreAuthorize on your method never trigger?
    Common causes: the class isn't a Spring bean, the method is called via self-invocation (this.method()) so it skips the proxy, or the method is private/final and can't be proxied.

saying these in an interview costs you the question

  • Thinking prePostEnabled must be set explicitly (it defaults to true).
  • Believing @Secured supports SpEL expressions (it only takes role name strings).
  • Assuming method security guards URLs — it guards method calls; URL rules live in the SecurityFilterChain.
  • Expecting self-invoked (this.x()) annotated calls to be secured.

context