Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get principal in Spring Boot resource server from JWT token

I have a separate auth server and a resource server - both Spring Boot applications. I am using OAuth2 with JWT tokens for authentication and authorisation.

I can get a token by accessing the auth server:

curl -X POST --user 'client:secret' -d 'grant_type=password&username=john&password=123' http://localhost:9000/auth-server/oauth/token

and use it when getting a resource from the resource server (running on different server) by attaching the token to the request header.

What is unclear to me though, is to determine which user is logged in in the resource server.

In the auth server, I can do something like this:

@RequestMapping("/user")
public Principal user(Principal user) {
    return user;
}

and this endpoint will get me the current user based on the token used. If I try to do the same thing in the resource server though, I only get empty response.

I need to get the id of the authenticated user somehow in the resource server to decide whether I should return some data to him (I have some resources which can be accessed only by their owner).

How could I do that? I thought that by using JWT, I don't need to share the same token store.

I can provide code samples if my question is not clear.. I am just looking for a confirmation that my assumption is correct and this behaviour can be achieved - this is my first time experimenting with spring security.

The resource server is linked to the auth server in the application.properties:

security.oauth2.resource.userInfoUri: http://localhost:9000/auth-server/user
like image 673
Smajl Avatar asked Aug 16 '16 13:08

Smajl


People also ask

What is principal in JWT token?

Each principal intended to process the JWT must identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the aud claim when this claim is present, then the JWT must be rejected.

How does resource server validate access token?

A resource server validates such a token by making a call to the authorisation server's introspection endpoint. The token encodes the entire authorisation in itself and is cryptographically protected against tampering. JSON Web Token (JWT) has become the defacto standard for self-contained tokens.

Where JWT token is stored in spring boot?

It is stored in-memory by default.

What is Spring Boot security with JWT?

For Spring Boot Security database authentication please refer here. We are going to cover – Spring Boot Security with JWT Example – Token Generation, Token Validation and Token Refresh. What is JWT? JWT stands for Json Web Token which is a token implementation in JSON format. Json tokens used for authentication and data sharing between parties.

Can we use JWT token in spring OAuth2?

The OAuth2 Authorization Server Previously, the Spring Security OAuth stack offered the possibility of setting up an Authorization Server as a Spring Application. We then had to configure it to use JwtTokenStore so that we could use JWT tokens.

What is OAuth2 resource server in Spring Boot?

oauth2ResourceServer (OAuth2ResourceServerConfigurer::jwt) — Configures the spring boot application as an OAuth2 Resource Server which authenticates all the incoming requests (except the ones excluded above) using JWT authentication. That is, all the requests should have an authorization header as below which contains a valid JWT.

Do I need to configure resource server to use JWT?

It issues JWT tokens by default, so there is no need for any other configuration in this regard. 3. Resource Server Now let's take a look at how to configure our Resource Server to use JWT.


1 Answers

This is what I did, for anyone who's stubbles across this (this method uses JWKs to validate JWTs).

You first need to setup a config bean that extends the WebSecurityConfigurerAdapter.class. Within the HttpSecurity object, you can use the oauth2ResourceServer.jet() method, which is pretty nice. It'll look for JWTs for incoming requests and set the Principal objects (and other objects as well) for incoming requests. It should look something like this:

@Configuration
@EnableWebSecurity(debug = true) //optional - helps with debugging your security filters.
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf()
            .disable()
            .antMatcher("/cars/**")
            .oauth2ResourceServer().jwt(); // validates the jwt token and also sets the authentication and principal

}

In the application.yml/.properties, you need to point to the JWK endpoint:

spring.security.oauth2.resourceserver.jwt.jwk-set-uri: <JWK_ENDPOINT>

In your controller, you can take the Principal and Authentication.

@RequestMapping(method = RequestMethod.GET, value = "/cars/{id}")
@ResponseBody
public Car getCar(@PathVariable("id") String id, Principal principal, Authentication auth) { 

    return new Car(id, "Ford", Color.BLUE, new Owner(principal.getName().toString(), 90120)); //the principal's name is a GUID

}

Alternatively, you can parse the JWT (because at this point, the BearerTokenAuthenticationFilter will have validated the JWT - in terms of expiration and other things) for reading the claims. This only works if you have a claim you're comfortable using.

like image 113
rj2700 Avatar answered Oct 08 '22 10:10

rj2700