How can the resource server identify the resource owner using token in oauth2?

652 Views Asked by At

The typical scenario I am looking into is:

  1. User1 provides proper credentials to the front-end rest client (grant type: password) and the client gets the token in return.
  2. The client sends the token and accesses the resources owned by User1.

In my scenario, once the client has the access token for user1, I want the client to have access limited to User1's resources only.

Consider that the client accesses the URI /users/1/books. The response will contain all the books associated with User1. The main problem is that if the client accesses the URL /users/2/books with User1's token, it gets the list of all the books for User2 which shouldn't be allowed.

How can I limit the scope to the user whose credentials were used to obtain the token?

How can I map the token to a specific user in my resource server?

I am using Spring/Java. But any general theory will also help.

1

There are 1 best solutions below

0
On BEST ANSWER

After a lot of debugging, I got the answer.

Spring security 1.4 Token store: InMemoryTokenStore()

In ResourceServerConfiguration, configure HttpSecurity.

@Override
public void configure(final HttpSecurity http) throws Exception {
    // @formatter:off
    http.authorizeRequests().
    // antMatchers("/oauth/token").permitAll().
    antMatchers("/api/users/{userId}").access("@webSecurity.checkUserId(authentication,#userId)")
    .anyRequest().authenticated().and().sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable();
    // @formatter:on
}

Create a class WebSecurity and provide the implementation.

public class WebSecurity {
    public boolean checkUserId(Authentication auth, int id) {
        return ((UmUser)auth.getPrincipal()).getId() == id;
    }
}

Resources: http://docs.spring.io/spring-security/site/docs/current/reference/html/el-access.html#el-access-web-path-variables

http://www.baeldung.com/get-user-in-spring-security

I had to debug a lot as I was using JwtTokenStore. This returned the Principal as a String and not the instance of UserDetails as I was expecting.

Once I switched to InMemoryTokenStore, I got the expected results. This was not a problem for me as I had the choice, but I would still like to know how to achieve it with the JWT.