skip to content

What are @Secured and @RolesAllowed in Spring Security, and what do they do?

level: juniorimportance: must knowfreq 55%

answer

  1. method-level role check
  2. @Secured needs full ROLE_ prefix
  3. @RolesAllowed = JSR-250, adds ROLE_
  4. no SpEL, multiple = OR
  5. must enable securedEnabled/jsr250Enabled

basics

~10 s

Both 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
java
@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

for a junior

Know both are method-level role gates and that @RolesAllowed is the Java-standard one.

for a middle

Must nail the ROLE_ prefix difference and that you have to enable each flag.

for a senior

Should articulate OR semantics, the no-SpEL/no-args limitation, and proxy self-call caveat.

for a principal

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

context