@PreAuthorize annotation
JavaSpring Boot

How to use @PreAuthorize annotation in a spring boot application

In Spring Boot, @PreAuthorize annotation is from the Spring Security framework that allows you to define method-level security rules for securing access to methods in your RESTful API endpoints. It enables you to specify fine-grained access control based on user roles, authorities, and other conditions, helping you enforce security policies at the method level.

To use @PreAuthorize in your Spring Boot application, you’ll need to set up Spring Security first. Here’s a step-by-step guide on how to use @PreAuthorize for securing API access in a @RestController:

Add Spring Security Dependency

Add Spring Security Dependency Ensure that you have the necessary Spring Security dependencies in your pom.xml (if using Maven) or build.gradle (if using Gradle) file.

Maven:

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

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-security'

Enable Global Method Security

Enable Global Method Security In your main Spring Boot application class, enable global method security using the @EnableGlobalMethodSecurity annotation. This allows the use of security annotations like @PreAuthorize.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

@PreAuthorize in your RestController

Use @PreAuthorize in your RestController Now you can use @PreAuthorize to secure your REST API methods. Place the @PreAuthorize annotation on top of the methods that require access control.

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class YourController {

    // Public endpoint accessible to all users
    @GetMapping("/api/public")
    public String publicEndpoint() {
        return "This is a public endpoint.";
    }

    // Restricted endpoint that requires ADMIN role
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/api/admin")
    public String adminEndpoint() {
        return "This is an admin endpoint, only accessible to users with ROLE_ADMIN.";
    }

    // Restricted endpoint that requires specific authority
    @PreAuthorize("hasAuthority('ROLE_MANAGE_USERS')")
    @GetMapping("/api/manage_users")
    public String manageUsersEndpoint() {
        return "This is a manage users endpoint, only accessible to users with ROLE_MANAGE_USERS authority.";
    }

    // Restricted endpoint with dynamic parameter checks
    @PreAuthorize("hasRole('ROLE_USER') and #id == authentication.principal.id")
    @GetMapping("/api/user/{id}")
    public String userEndpoint(@PathVariable Long id) {
        return "This is a user-specific endpoint, only accessible to users with ROLE_USER and their own ID.";
    }
}

In this example, we’ve used various expressions with @PreAuthorize:

  • "hasRole('ROLE_ADMIN')": Only users with the role “ROLE_ADMIN” can access the adminEndpoint().
  • "hasAuthority('ROLE_MANAGE_USERS')": Only users with the authority “ROLE_MANAGE_USERS” can access the manageUsersEndpoint().
  • "hasRole('ROLE_USER') and #id == authentication.principal.id": The userEndpoint() requires the user to have “ROLE_USER” and the id path variable must match the authenticated user’s ID.

Configure Authentication and Authorization

Configure Authentication and Authorization To set up the authentication and authorization configuration, create a security configuration class that extends WebSecurityConfigurerAdapter. This is where you can define your authentication provider, user details service, and other security-related configurations.

import org.springframework.beans.factory.annotation.Autowired;
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;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // Configure your authentication provider or user details service here
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/api/public").permitAll()
            .anyRequest().authenticated()
            .and().httpBasic();
        // You can further configure other security aspects like CSRF, CORS, etc.
    }
}

In this example, we’ve allowed access to the /api/public endpoint for all users (permitAll()), while other endpoints require authentication.

That’s it! With the @PreAuthorize annotation and Spring Security configuration in place, you can now secure your RESTful API access at the method level based on user roles, authorities, and other conditions. Remember to configure the authentication provider and user details service based on your application’s requirements.

Note: The specific security requirements and expressions may vary depending on your application’s needs. Always design your security model based on the principle of least privilege and thoroughly test your security configurations to ensure they meet your application’s security objectives.

You can refer the following for details – @PreAuthorize annotation.

In the last BitsToGigs post we had discussed about How to use @Profile annotation.

Happy Learning!

Subscribe to the BitsToGigs Newsletter

What's your reaction?

Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0

You may also like

More in:Java

Leave a reply

Your email address will not be published. Required fields are marked *