Hey guys in this post, we will discuss Spring security method level annotation @PreAuthorize
with complete code example
Table of Contents
Overview
- The
@PreAuthorize
can check for authorization before entering into method. - The
@PreAuthorize
authorizes on the basis of role or the argument which is passed to the method.
Complete Example
We will create this example step by step, follow this tutorial till the end
Read More:
- Check the Complete JavaServer Faces (JSF) Tutorial
- Check the Complete Spring Data JPA Tutorial
- Check the Complete Spring Security Tutorial
- Check the Javascript Projects for Beginners
- Check the Spring Boot JdbcTemplate Tutorials
Create spring boot project
There are many different ways to create a spring boot application, you can follow the below articles to create one –
>> Create spring boot application using Spring initializer
>> Create spring boot application in Spring tool suite [STS]
>> Create spring boot application in IntelliJ IDEA
Add maven dependencies
Open pom.xml
and add the following dependencies –
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>in.bushansirgur</groupId>
<artifactId>springsecurityexample</artifactId>
<version>1.0.0</version>
<name>springsecurityexample</name>
<description>Spring security example</description>
<properties>
<java.version>16</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
spring-boot-starter-web
dependency for building web applications using Spring MVC. It uses the tomcat as the default embedded container. spring-boot-starter-security
dependency, which will help to implement spring security.
Create configuration class
Create SecurityConfig.java
class inside in.bushansirgur.springsecurityexample.config
package and add the following contents
package in.bushansirgur.springsecurityexample.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/**").permitAll()
.anyRequest().authenticated().and().httpBasic();
}
@Override
@Bean
protected UserDetailsService userDetailsService() {
UserDetails bushan = User.builder().username("bushan").password(passwordEncoder().encode("password")).roles("USER").build();
UserDetails admin = User.builder().username("admin").password(passwordEncoder().encode("password")).roles("ADMIN").build();
return new InMemoryUserDetailsManager(bushan, admin);
}
}
We are extending this class with WebSecurityConfigurerAdapter
, as we are customizing the spring security. We are customizing the UserDetailsService
by adding 2 users which is having roles Admin
and User
. For the simplicity we are using InMemoryUserDetailsManager()
. We are calling httpBasic()
to use the basic http authentication.
In order to use method level security, we need to add annotation @EnableGlobalMethodSecurity(prePostEnabled = true
)
Create a controller
Create HomeController.java
class inside in.bushansirgur.springsecurityexample.controller
package and add the following content
package in.bushansirgur.springsecurityexample.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@GetMapping("/foradmin")
@PreAuthorize("hasRole('ADMIN')")
public String forAdmin() {
return "this page is accessible only by admin";
}
@GetMapping("/foruser")
@PreAuthorize("hasRole('USER')")
public String forUser() {
return "this page is accessible only by user";
}
}
@PreAuthorize("hasRole('USER')")
annotation executes the method if the user is having role User
, similarly @PreAuthorize("hasRole('ADMIN')")
annotation executes the method if the user is having role Admin
.
Run the app
Run the application using the below maven command –
mvn spring-boot:run
Open the browser and enter the following URL –
http://localhost:8080/foradmin
—
—
That’s it for this post, if you like this post, share this with your friends and colleagues or you can share this within your social media platform. Thanks, I will see you in our next post.