Spring Security Role Based Authorization Example


This guide shows you how to configure role-based authorization in Spring Security. To work with Spring Security authorization, we have to override the configure(HttpSecurity http) method of WebSecurityConfigurerAdapter and authorized every request based on the logged-in user role.

What we’ll build

In this example, we will create a Spring Boot application and authorized every request based on the logged-in user role. To do that we need the following:

1. Roles that assigned to the user on which user authorized to access the URL/page:

private static final String ROLE_1 = "ADMIN";
private static final String ROLE_2 = "USER";

2. Users with different roles:

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

For demonstration, we have used In-Memory authentication.

3. Authorization every request based on the logged-in user role/roles:

@Override
protected void configure(HttpSecurity http) throws Exception {
	http.authorizeRequests()
			.antMatchers("/admin").hasRole(ROLE_1)
			.antMatchers("/user").hasAnyRole(ROLE_2, ROLE_1)
			.antMatchers("/all").permitAll()
			.and().formLogin();	
}

4. And some endpoints to accessed by a user based on the assigned role.

Similar Post:

  1. Spring Boot + Spring Security with JPA authentication and MySQL
  2. Spring Security JDBC authentication with Spring Boot

Technology Used

Find the list of all technologies used in this application.

  1. Spring Tool Suite 4
  2. JDK 8
  3. Spring Boot 2.1.7.RELEASE
  4. Spring Security 5.1.6.RELEASE
  5. Maven 3

Dependencies Required

To resolve the JAR dependency, add the following code to your pom.xml.

pom.xml
<?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.1.7.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>org.websparrow</groupId>
	<artifactId>spring-security-authorization</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-security-authorization</name>
	<description>Demo project for Spring Secuirty Authorization</description>
	<properties>
		<java.version>1.8</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>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Project Structure

The final project structure of our application in STS 4 IDE will look like as follows:

Spring Security Role Based Authorization Example

Now, let’s jump to the actual piece of coding.

1. Endpoints for User

Create some endpoints/pages to be accessed by users based on their roles. In this controller, I have created 3 REST endpoints i.e.

  1. /admin → accessed by the user has a role of “ADMIN“.
  2. /user → accessed by the user has the role of “USER/ADMIN“. Of course, ADMIN can access everything.
  3. /all → accessed by all. No need to log in.
MyController.java
package org.websparrow.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

	@GetMapping("/admin")
	public String admin() {

		return "<h2>Welcome Admin!</h2>";
	}

	@GetMapping("/user")
	public String user() {

		return "<h2>Welcome User!</h2>";
	}

	@GetMapping("/all")
	public String all() {

		return "<h2>Hello Everyone!</h2>";
	}
}

2. Security Configuration

To limit the access of the user, we need to extend the WebSecurityConfigurerAdapter class and overrides it’s configure(HttpSecurity http) method and authorized every request based on the logged-in user role.

1. /admin → accessed by the user has a role of “ADMIN“.
2. /user → accessed by the user has the role of “USER/ADMIN“. Of course, ADMIN can access everything.
3. /all → accessed by all. No need to log in.

SecurityConfiguration.java
package org.websparrow.configuration;

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.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
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
	
	// Roles for users
	private static final String ROLE_1 = "ADMIN";
	private static final String ROLE_2 = "USER";
	
	// In-memory users with roles
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {		
		auth.inMemoryAuthentication()
				.withUser("admin")
				.password(passwordEncoder().encode("admin@123"))
				.roles(ROLE_1)
				.and()
				.withUser("user")
				.password(passwordEncoder().encode("user@123"))
				.roles(ROLE_2);
	}
	
	// Password encoding
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	// Authorized the request based on role
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
				.antMatchers("/admin").hasRole(ROLE_1)
				.antMatchers("/user").hasAnyRole(ROLE_2, ROLE_1)
				.antMatchers("/all").permitAll()
				.and().formLogin();
	}
}

Don’t forget to add @Configuration and @EnableWebSecurity annotation at the class level of your custom security configuration class.

3. Run the application

The SecurityApp class contains the main method and responsible to start the application.

SecurityApp.java
package org.websparrow;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SecurityApp {

	public static void main(String[] args) {
		SpringApplication.run(SecurityApp.class, args);
	}
}

4. Test the application

To test the application, start the Spring Boot application by executing the above class and follow the below steps:

For /admin page:

  1. Hit the localhost:8080/admin, it will redirect you to the login page.
  2. Log in with the user has a role “ADMIN” and after successful authentication, it will show you the admin page.
  3. Similarly, try to access the admin URL with user don’t have the role of “ADMIN” (user has a role “USER“), Spring Security will block you to access the admin page.

For /user page:

  1. Hit the localhost:8080/user, it will redirect you to the login page.
  2. Log in with the user has a role “USER” and after successful authentication, it will show you the user page.
  3. User has a role “ADMIN” can also access it.

For /all page:

  1. Spring Security allows localhost:8080/all URL to be accessed by everyone. It doesn’t require to be authenticated.

References

  1. Getting Started with Spring Security
  2. Spring Security- How to change default username and password
  3. Spring Security – Authorize Requests

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.