What are @Secured and @RolesAllowed in Spring Security, and what do they do?
answer
- method-level role check
- @Secured needs full ROLE_ prefix
- @RolesAllowed = JSR-250, adds ROLE_
- no SpEL, multiple = OR
- must enable securedEnabled/jsr250Enabled
basics
~10 sBoth are method-level annotations that restrict who can call a method based on their roles. @RolesAllowed is a Java standard (JSR-250); @Secured is Spring's own. You list allowed roles and Spring blocks everyone else.
solid answer
~40 s@Secured and @RolesAllowed are declarative, method-level authorization annotations. You put them on a service (or controller) method and Spring Security checks the authenticated user's authorities before the method runs, throwing AccessDeniedException if none match. @Secured is Spring-specific and takes the full authority string, e.g. @Secured("ROLE_ADMIN"). @RolesAllowed comes from JSR-250 (jakarta.annotation.security.RolesAllowed), is framework-neutral, and takes the role name without the prefix, e.g. @RolesAllowed("ADMIN"). Both do plain role/authority matching only — no SpEL, no access to method arguments. Multiple listed roles mean OR (any match grants access). Neither is active by default; you must enable them via @EnableMethodSecurity(securedEnabled = true) and/or (jsr250Enabled = true).
code
java · 13 lines@Configuration
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig { }
@Service
public class UserService {
@Secured("ROLE_ADMIN") // full authority, no prefix added
public void purge(Long id) { ... }
@RolesAllowed("ADMIN") // ROLE_ prefix added automatically
public void reset(Long id) { ... }
}go deeper
Know both are method-level role gates and that @RolesAllowed is the Java-standard one.
Must nail the ROLE_ prefix difference and that you have to enable each flag.
Should articulate OR semantics, the no-SpEL/no-args limitation, and proxy self-call caveat.
Frame the choice as a portability/simplicity vs expressiveness trade-off across a codebase.
## What they are **Method security** means enforcing authorization at the method level rather than only on URLs. Spring Security intercepts calls to annotated methods (via a Spring AOP proxy) and checks the current user's *authorities* before letting the method execute. **@Secured** is a Spring Security annotation. It takes one or more authority strings and grants access if the user has *any* of them: ```java @Secured("ROLE_ADMIN") public void deleteUser(Long id) { ... } ``` Important: @Secured does **not** add the `ROLE_` prefix for you. You must write the *complete* authority name (`ROLE_ADMIN`, not `ADMIN`). **@RolesAllowed** is from **JSR-250** (the `jakarta.annotation.security` package, formerly `javax.annotation.security`). It is a Java-standard annotation, not Spring-specific, so it also works in Jakarta EE containers. It takes *role names* and Spring automatically prepends the `ROLE_` prefix: ```java @RolesAllowed("ADMIN") // matches authority ROLE_ADMIN public void deleteUser(Long id) { ... } ``` ## Key terms - **Authority**: a granted permission string on the user (e.g. `ROLE_ADMIN`, `SCOPE_read`). In Spring these are `GrantedAuthority` objects. - **Role**: by convention an authority that starts with `ROLE_`. "Role X" means authority `ROLE_X`. - **AccessDeniedException**: thrown when the check fails; results in HTTP 403 for web requests (or a redirect for anonymous users depending on config). ## How access is decided Both annotations do a simple membership test: does the user have at least one of the listed authorities? If yes, the method runs; if no, `AccessDeniedException` is thrown *before* the method body executes. Multiple values are **OR-ed**: ```java @Secured({"ROLE_ADMIN", "ROLE_AUDITOR"}) // admin OR auditor ``` There is **no way to express AND** with these annotations, and **no SpEL** — you cannot inspect method arguments or call `hasPermission`. ## Enabling them Neither is on by default. In Spring Security 6 use: ```java @Configuration @EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) public class SecurityConfig {} ``` `prePostEnabled` (for @PreAuthorize/@PostAuthorize) defaults to `true`; `securedEnabled` and `jsr250Enabled` default to `false`, so you must opt in. ## Gotchas - Writing `@Secured("ADMIN")` silently checks for authority `ADMIN`, which almost never exists — the user is denied. Always include `ROLE_`. - Writing `@Secured("hasRole('ADMIN')")` does **not** evaluate SpEL — the whole string is treated as a literal authority name and never matches. - The annotations only work through the Spring proxy: an internal `this.method()` self-call bypasses the check, and by default only `public` methods are advised. ## When to use Use @RolesAllowed or @Secured for simple, static, role-only checks where their brevity is a virtue. Reach for @PreAuthorize when you need SpEL — argument-based rules, combining conditions, or `hasAnyRole` plus custom logic.
- Are these checks on by default when you add @EnableMethodSecurity?No. Only prePostEnabled (@PreAuthorize) defaults to true. You must set securedEnabled = true and/or jsr250Enabled = true to activate @Secured and @RolesAllowed respectively.
- What happens when the check fails?Spring Security throws AccessDeniedException before the method body runs; for web requests this maps to HTTP 403 (or triggers the authentication entry point for anonymous users).
saying these in an interview costs you the question
- Thinking @Secured adds the ROLE_ prefix like hasRole does
- Believing @Secured can evaluate SpEL such as hasRole('ADMIN')
- Assuming method security is enabled automatically without securedEnabled/jsr250Enabled