How to implement authorization using JWT/OAuth2 in Spring Boot?

happy female demonstrating name tag
Photo by Angela Roma on Pexels.com

There are two main aspects in Security:

  1. Authentication
  2. Authorization

Authentication deals with whether the user who tries to access an application is a legitimate user.

Authorization deals with whether the user has rights to read/modify a particular resource in the application.

In this post let us look into authorization in Spring Boot.

Let us consider an application protected by OAuth2 (Authentication).

If you want to know how to do authentication using OAuth2

To implement Authorization on top of this, we need to follow the below steps:

  1. Create roles/scopes on authorization server.
  2. Add configuration for authorizing the created roles.

STEP 1: Create Role/Scope

Before creating the scopes you should set up the authorization server.

Refer the below post for the same :

Now let us create a client and assign some roles.

We use “scopes” in OAuth2 instead of “roles” for authorization.

Spring Boot automatically looks for scopes in the JWT token generated which is sent along with the request to the REST API.

And then it will check whether that “scope” is valid one to access the REST API.

Run the authorization server (in my case it is keycloak) and login to the admin console.

Create an oauth 2 client as explained in the article on KeyCloak authorization server setup.

Then create a new client scope:

I have created a new scope called “admin_user” for admin role.

Map this scope to the client you created(in this example “oauth_test”) by selecting clients and then client scopes tab in the menu:

Now the client “oauth_test” has got the role/scope “admin_user”.

Now let’s configure our spring boot app to allow certain APIs to be accessed only by admin_user

STEP 2: Add Authorization configuration

Add the below configuration in a configuration class in your spring boot app:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {


http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/admin")
.hasAuthority("SCOPE_admin_user")
.anyRequest()
.authenticated())
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
}

The above is a normal configuration class in spring boot (annotated with @Configuration) .

Add @EnableWebSecurity annotation as well.

Then create a SecurityFilterChain bean using a method like above.

You specify authorization for a particular path in the URL.

In the above case the url ending with “/admin” is allowed only for the scope “SCOPE_admin_user”

The word “SCOPE” is automatically in the request token so we have mentioned it here.

Here is a sample controller class to test it:

@RestController
public class TestController {

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

return "Hello Admin!";
}
}

Now if you start the app and hit the url “/admin” with oauth token , Spring will extract the scope from the token and allow the user to access the API only if the scope is “admin_user”.

I generated the token using postman tool.

You can decode the token on jwt.io website and see the scope you assigned:

Spring will allow access to the /admin API only if the above scope is present.

You can experiment adding new scopes and assigning them to different paths.

Here is the updated configuration with one more role configured:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/admin")
.hasAuthority("SCOPE_admin_user")
.requestMatchers("/special") .hasAnyAuthority("SCOPE_admin_user", "SCOPE_special_user")
.anyRequest()
.authenticated())
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}

Any hit to the URL ending with “/special” should have the scope “special_user” as per the above configuration.

Here is the entire code:

vijaysrj/oauth2-authorization-app (github.com)

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading