Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

Spring Security Annotations

Spring Security provides a set of annotations to handle authentication and authorization at the method level. These annotations simplify the process of securing methods within your Spring applications. This guide covers the key Spring Security annotations and how to use them effectively.

Key Spring Security Annotations

  • @EnableWebSecurity: Enables Spring Security’s web security support and provides the Spring MVC integration.
  • @PreAuthorize: Specifies a method should be accessible only if the specified expression evaluates to true before the method is invoked.
  • @PostAuthorize: Specifies a method should be accessible only if the specified expression evaluates to true after the method is invoked.
  • @Secured: Specifies one or more roles that are allowed to invoke a method.
  • @RolesAllowed: Similar to @Secured but uses standard JSR-250 annotations.
  • @EnableGlobalMethodSecurity: Enables method-level security.

Setting Up Dependencies

Include the Spring Security dependency in your pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Enabling Method-Level Security

Enable method-level security by adding the @EnableGlobalMethodSecurity annotation in your configuration class:

Example: SecurityConfiguration.java

// SecurityConfiguration.java
package com.example.myapp.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {
    // Security configuration code
}

Using @PreAuthorize

The @PreAuthorize annotation is used to specify an authorization expression that will be evaluated before a method is invoked:

Example: MyService.java

// MyService.java
package com.example.myapp.service;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @PreAuthorize("hasRole('ADMIN')")
    public void adminMethod() {
        // Admin only logic
    }

    @PreAuthorize("hasRole('USER')")
    public void userMethod() {
        // User only logic
    }
}

Using @PostAuthorize

The @PostAuthorize annotation is used to specify an authorization expression that will be evaluated after a method is invoked:

Example: MyService.java

// MyService.java
package com.example.myapp.service;

import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @PostAuthorize("returnObject.owner == authentication.name")
    public MyObject getObject() {
        // Method logic
        return new MyObject();
    }
}

Using @Secured

The @Secured annotation is used to specify one or more roles that are allowed to invoke a method:

Example: MyService.java

// MyService.java
package com.example.myapp.service;

import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Secured("ROLE_ADMIN")
    public void adminMethod() {
        // Admin only logic
    }

    @Secured({"ROLE_USER", "ROLE_ADMIN"})
    public void userOrAdminMethod() {
        // User or Admin logic
    }
}

Using @RolesAllowed

The @RolesAllowed annotation is similar to @Secured but uses standard JSR-250 annotations:

Example: MyService.java

// MyService.java
package com.example.myapp.service;

import javax.annotation.security.RolesAllowed;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @RolesAllowed("ROLE_ADMIN")
    public void adminMethod() {
        // Admin only logic
    }

    @RolesAllowed({"ROLE_USER", "ROLE_ADMIN"})
    public void userOrAdminMethod() {
        // User or Admin logic
    }
}

Example: Full Configuration and Service

Here is a full example combining security configuration and service method annotations:

Example: SecurityConfiguration.java

// SecurityConfiguration.java
package com.example.myapp.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
            .password(passwordEncoder().encode("password"))
            .roles("USER")
            .and()
            .withUser("admin")
            .password(passwordEncoder().encode("admin"))
            .roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Example: MyService.java

// MyService.java
package com.example.myapp.service;

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @PreAuthorize("hasRole('ADMIN')")
    public void adminMethod() {
        // Admin only logic
    }

    @PreAuthorize("hasRole('USER')")
    public void userMethod() {
        // User only logic
    }

    @PostAuthorize("returnObject.owner == authentication.name")
    public MyObject getObject() {
        // Method logic
        return new MyObject();
    }

    @Secured("ROLE_ADMIN")
    public void securedAdminMethod() {
        // Admin only logic
    }

    @Secured({"ROLE_USER", "ROLE_ADMIN"})
    public void securedUserOrAdminMethod() {
        // User or Admin logic
    }

    @RolesAllowed("ROLE_ADMIN")
    public void rolesAllowedAdminMethod() {
        // Admin only logic
    }

    @RolesAllowed({"ROLE_USER", "ROLE_ADMIN"})
    public void rolesAllowedUserOrAdminMethod() {
        // User or Admin logic
    }
}

Key Points

  • @EnableWebSecurity: Enables Spring Security’s web security support and provides the Spring MVC integration.
  • @PreAuthorize: Specifies a method should be accessible only if the specified expression evaluates to true before the method is invoked.
  • @PostAuthorize: Specifies a method should be accessible only if the specified expression evaluates to true after the method is invoked.
  • @Secured: Specifies one or more roles that are allowed to invoke a method.
  • @RolesAllowed: Similar to @Secured but uses standard JSR-250 annotations.
  • @EnableGlobalMethodSecurity: Enables method-level security.
  • Enable method-level security by adding the @EnableGlobalMethodSecurity annotation in your configuration class.
  • Use @PreAuthorize and @PostAuthorize to secure methods with authorization expressions.
  • Use @Secured and @RolesAllowed to specify roles that can invoke methods.
  • Combine security configuration and service method annotations to secure your Spring Boot application effectively.

Conclusion

Spring Security annotations provide a powerful and declarative way to secure methods in your Spring Boot applications. By understanding and using these annotations effectively, you can implement fine-grained security controls and ensure that your application is protected against unauthorized access. Happy coding!