Recreate the Access Denied Error
Import a new project in the IDE of your choice and add the following dependencies to it:
- Spring Web
- Spring Security
The dependencies tag in your pom.xml file must contain these:
<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>
Next, create a controller class as follows:
Java
//Controller layer of application import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; @RestController @RequestMapping ( "/api/v1" ) public class MyController { /** * GET endpoint for public message. * Accessible by both USERS and ADMINS. * * @return Public message */ @GetMapping ( "/public" ) public String publicMessage() { return "This is a PUBLIC endpoint. USERS and ADMINS can access it." ; } /** * GET endpoint for private message. * Accessible only by ADMINS. * * @return Private message */ @GetMapping ( "/secured" ) public String privateMessage() { return "This is a PRIVATE endpoint. Only ADMINS can access it." ; } } |
In the above code sample, we intend to keep the public endpoints accessible to all users whereas the secured endpoints are visible to admins only.
Next, create a SecurityConfig.java class as follows:
Java
//Configuration Layer import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { /** * Configures Spring Security's HTTP request authorization. * * @param http HttpSecurity object for customization * @return SecurityFilterChain Spring Security filterChain * @throws Exception */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // Authorize requests based on URL patterns and // user roles .authorizeHttpRequests( authorize -> authorize .requestMatchers( "/api/v1/secured" ) .hasRole( "ADMIN" ) // Only admins can access .requestMatchers( "/api/v1/public" ) .hasAnyRole( "ADMIN" , "USER" ) // Both admins and users can access .anyRequest() .authenticated()) // All other // requests require // authentication // Enable form login for authenticating users .formLogin(Customizer.withDefaults()) // Enable Basic authentication for providing API access .httpBasic(Customizer.withDefaults()); return http.build(); } /** * Creates an in-memory user details service with * predefined users. * * @return UserDetailsService with test users */ @Bean public UserDetailsService users() { User.UserBuilder users = User.withDefaultPasswordEncoder(); UserDetails user = users.username( "user" ) .password( "test123" ) .roles( "USER" ) .build(); UserDetails admin = users.username( "admin" ) .password( "test123" ) .roles( "USER" , "ADMIN" ) .build(); return new InMemoryUserDetailsManager(user, admin); } } |
First, we configure spring security to allow only admins to access the secure endpoint. Next, we set up spring security to allow all users to access the public endpoint.
Next, we build users in memory as follows:
- user 1 – username=user, password=test123, role= USER
- user 2- username=admin, password=test123, role= USER, ADMIN
Now try running the code and fire up a private window in your computer. We will be testing 2 things:
- We will log in as `user` and we should be able to access the public endpoint only. We will also see the error when we try to visit the secured endpoint.
- We will log in as `admin` and we should be able to access all endpoints. No errors.
Let’s get started:
1. Login as a User
- Before implementing the Access Denied Request, login as user
- Accessing the public endpoint after login as user
- Accessing the private/secured endpoint after login as user
2. Login as ADMIN
- Before implementing the Access Denied Request, login as Adminuser
- Accessing the public endpoint after login as Admin
- Accessing the private/secured endpoint after login as admin
Spring REST – Response for Access Denied Request
The Access Denied Request has an error code of 403. This is the error that is generated when the user tries to access certain resources that he is not authorized. The system displays a whitelabel error displaying the status code 403.
In this article, let us regenerate this error using spring security and then handle the same effectively using spring security.
Prerequisite Knowledge of role-based authorization in spring is required for the topic.
Contact Us