Skip to main content

Command Palette

Search for a command to run...

Spring Security Annotations

A declarative approach to access control

Published
•3 min read•View as Markdown
Spring Security Annotations

Annotations provide an elegant way to implement authorization in Spring Security. Below are key annotations and their usage:


  1. 1. @Secured

    Purpose: Restricts access to methods or classes based on a list of roles.
    Key Details:

    • Roles are specified as a comma-separated list (e.g., {"ROLE_ADMIN", "ROLE_USER"}).

    • Does not support SpEL (unlike @PreAuthorize).

    • Requires @EnableGlobalMethodSecurity(securedEnabled = true) in the configuration.

Example:

    @Secured({"ROLE_ADMIN", "ROLE_SUPER_ADMIN"})
    public void createUser(User user) {
        // Logic for creating a user
    }

2. @PreAuthorize

Purpose: Evaluates a SpEL expression before method execution to grant/deny access.
Key Details:

  • Supports complex expressions (e.g., #userId == principal.id).

  • Requires @EnableGlobalMethodSecurity(prePostEnabled = true).

Example:

    @PreAuthorize("hasRole('ROLE_ADMIN') or #userId == authentication.principal.id")
    public void deleteAdminUser(Long userId) {
        // Logic
    }

3. @PostAuthorize

Purpose: Evaluates a SpEL expression after method execution, often to filter the return value.
Key Details:

  • Useful for post-execution checks (e.g., verifying ownership of returned data).

Example:

    @PostAuthorize("returnObject.owner == authentication.name")
    public Document getDocument(Long id) {
        // Logic
    }

4. @PreFilter

Purpose: Filters input collections before method execution based on a SpEL condition.
Key Details:

  • Applies to method parameters (e.g., List<T>, Array).

  • The filterObject keyword refers to each item in the collection.

Example:

    @PreFilter("filterObject.owner == authentication.name")
    public void deleteDocuments(List<Document> documents) {
        // Logic (only processes documents owned by the current user)
    }

5. @PostFilter

Purpose: Filters returned collections after method execution using SpEL.
Key Details:

  • Removes items from the result that don’t match the condition.

Example:

    @PostFilter("hasRole('ROLE_ADMIN') or filterObject.isPublic")
    public List<Course> findAllCourses() {
        // Logic (returns only public courses or all courses for admins)
    }

6. @RolesAllowed (JSR-250)

Purpose: Specifies allowed roles (similar to @Secured but standardized).
Key Details:

  • Part of javax.annotation.security (not Spring-specific).

  • Does not support SpEL.

  • Requires @EnableGlobalMethodSecurity(jsr250Enabled = true).

Example:

    @RolesAllowed("ROLE_ADMIN")
    public void deleteCourse(Long courseId) {
        // Logic
    }

7. @AuthenticationPrincipal

Purpose: Injects the current authenticated user (e.g., UserDetails, String username).
Key Details:

  • Works with @EnableWebSecurity or @EnableGlobalMethodSecurity.

Example:

    @GetMapping("/me")
    public String getUsername(@AuthenticationPrincipal UserDetails user) {
        return user.getUsername();
    }

8. Role Hierarchies

Purpose: Simplifies security configurations by defining role inheritance.
Key Details:

  • Configured as a bean (not an annotation!).

  • Example: ROLE_SUPER_ADMIN > ROLE_ADMIN > ROLE_USER means higher roles inherit lower permissions.

Configuration Example:

    @Bean
    public RoleHierarchy roleHierarchy() {
        String hierarchy = "ROLE_SUPER_ADMIN > ROLE_ADMIN > ROLE_USER";
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy(hierarchy);
        return roleHierarchy;
    }

Key Takeaways

  1. Method Security: Annotations like @PreAuthorize and @Secured control access at the method level.

  2. SpEL: Used in @Pre/PostAuthorize and @Pre/PostFilter for dynamic expressions.

  3. JSR-250: @RolesAllowed is a Java standard, while @Secured is Spring-specific.

  4. Role Hierarchies: Reduce redundancy by defining role relationships in a bean.

For full security setup, enable annotations in your configuration:

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)