Spring Security method level annotation @PreAuthorize Example





Hey guys in this post, we will discuss Spring security method level annotation @PreAuthorize with complete code example

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:

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
Screenshot-2021-08-09-at-10-04-06-PM

Screenshot-2021-08-09-at-10-04-31-PM

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.



Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

Leave a Reply