Lesson 3: Tokens, OAuth2 and JWT (legacy stack)

1. Goals

Understand what tokens are, why JWT is a solid option and how to set it up with Spring Security.


2. Lesson Notes

The relevant module you need to import when you're starting with this lesson is: m6-lesson3


Token Implementations

SAML (or the WS* space)
- XML based

- many encryption and signing options

- expressive but you need a pretty advanced XML stack


Simple Web Token

- joint venture between Microsoft, Google, Yahoo

- created as a direct reaction to making a much simpler version of SAML

- too simple, not enough cryptographic options (just symetric)


JWT (JSON Web Tokens)

- the idea is that you are representing the token using JSON (widely supported)

- symmetric and asymmetric signatures and encryption

- less options/flexibility than SAML but more than SWT

- JWT hit the sweet spot and became widely adopted pretty quickly

- JWT - an emerging protocol (very close to standardization)

JWT structure

- a JWT token has 2 parts:
1. Header
- metadata
- info about algos / keys used

2. Claims
- Reserved Claims (issuer , audience, issued at, expiration, subject, etc)

- Application specific Claims

JWT with Spring Security OAuth

For the Authorization Server:

- we’re defining the JwtAccessTokenConverter bean and the JwtTokenStore

- we’re also configuring the endpoint to use the new converter

Note that we're using symmetric signing - with a shared signing key.

For the Resource Server:

- we should define the converter here as well, using the same signing key

Note that we don’t have to because we’re actually sharing the same Spring context in this case. If the Authorization Server would have been a separate app - then we would have needed this converter, configured exactly the same as in the Resource Server.


Upgrade Notes

As we've already mentioned in the previous lesson, in Spring Boot 2, it is now required to encode passwords. To this end, we should define a PasswordEncoder bean and use it in order to encode the secret when configuring the client in the AuthorizationServerConfiguration class:

@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
     ...
    .secret(passwordEncoder.encode("bGl2ZS10ZXN0"))
     ...
}

and when configuring the UserDetailsService in the ResourceServerConfiguration class:

@Bean
public AuthenticationProvider authProvider() {
    final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder);
    return authProvider;
}

In the lessons, we use the BCryptPasswordEncoder implementation of the PasswordEncoder interface:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

Check the JWT Access Token

After enabling the JWS access token, use the following details to retrieve the JWT token.

POST

http://localhost:8082/um-webapp/oauth/token?grant_type=password&client_id=live-test&username=admin@fake.com&password=adminpass

Authorization username and password: live-test: bGl2ZS10ZXN0

3. Resources

- jwt.io

- Spring Security and Angular JS

RwS - Tokens, OAuth2 and JWT - transcript.pdf
Complete and Continue