Add NimbusJwtDecoder Documentation

Fixes gh-7408
This commit is contained in:
Josh Cummings 2019-09-11 13:44:08 -06:00
parent 101e0a21a8
commit 33fb93f0ea
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443

View File

@ -597,7 +597,7 @@ More powerful than `jwkSetUri()` is `decoder()`, which will completely replace a
```java
@EnableWebSecurity
public class DirectlyConfiguredJwkSetUri extends WebSecurityConfigurerAdapter {
public class DirectlyConfiguredJwtDecoder extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) {
http
.authorizeRequests()
@ -624,6 +624,157 @@ public JwtDecoder jwtDecoder() {
}
```
[[oauth2resourceserver-jwt-decoder-algorithm]]
=== Configuring Trusted Algorithms
By default, `NimbusJwtDecoder`, and hence Resource Server, will only trust and verify tokens using `RS256`.
You can customize this via <<oauth2-resourceserver-jwt-boot-algorithm,Spring Boot>>, <<oauth2-resourceserver-jwt-decoder-builder,the NimbusJwtDecoder builder>>, or from the <<oauth2-resourceserver-jwt-decoder-jwk-response,JWK Set response>>.
[[oauth2-resourceserver-jwt-boot-algorithm]]
==== Via Spring Boot
The simplest way to set the algorithm is as a property:
```yaml
spring:
security:
oauth2:
resourceserver:
jwt:
jws-algorithm: RS512
jwk-set-uri: https://idp.example.org/.well-known/jwks.json
```
[[oauth2-resourceserver-jwt-decoder-builder]]
==== Using a Builder
For greater power, though, we can use a builder that ships with `NimbusJwtDecoder`:
```java
@Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.fromJwkSetUri(this.jwkSetUri)
.jwsAlgorithm(RS512).build();
}
```
Calling `jwsAlgorithm` more than once will configure `NimbusJwtDecoder` to trust more than one algorithm, like so:
```java
@Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.fromJwkSetUri(this.jwkSetUri)
.jwsAlgorithm(RS512).jwsAlgorithm(EC512).build();
}
```
Or, you can call `jwsAlgorithms`:
```java
@Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.fromJwkSetUri(this.jwkSetUri)
.jwsAlgorithms(algorithms -> {
algorithms.add(RS512);
algorithms.add(EC512);
}).build();
}
```
[[oauth2-resourceserver-jwt-decoder-jwk-response]]
==== From JWK Set response
Since Spring Security's JWT support is based off of Nimbus, you can use all it's great features as well.
For example, Nimbus has a `JWSKeySelector` implementation that will select the set of algorithms based on the JWK Set URI response.
You can use it to generate a `NimbusJwtDecoder` like so:
```java
@Bean
public JwtDecoder jwtDecoder() {
// makes a request to the JWK Set endpoint
JWSKeySelector<SecurityContext> jwsKeySelector =
JWSAlgorithmFamilyJWSKeySelector.fromJWKSetURL(this.jwkSetUrl);
DefaultJWTProcessor<SecurityContext> jwtProcessor =
new DefaultJWTProcessor<>();
jwtProcessor.setJWSKeySelector(jwsKeySelector);
return new NimbusJwtDecoder(jwtProcessor);
}
```
[[oauth2resourceserver-jwt-decoder-public-key]]
=== Trusting a Single Asymmetric Key
Simpler than backing a Resource Server with a JWK Set endpoint is to hard-code an RSA public key.
The public key can be provided via <<oauth2resourceserver-jwt-decoder-public-key-boot,Spring Boot>> or by <<oauth2resourceserver-jwt-decoder-public-key-builder,Using a Builder>>.
[[oauth2resourceserver-jwt-decoder-public-key-boot]]
==== Via Spring Boot
Specifying a key via Spring Boot is quite simple.
The key's location can be specified like so:
```yaml
spring:
security:
oauth2:
resourceserver:
jwt:
public-key-location: classpath:my-key.pub
```
Or, to allow for a more sophisticated lookup, you can post-process the `RsaKeyConversionServicePostProcessor`:
```java
@Bean
BeanFactoryPostProcessor conversionServiceCustomizer() {
return beanFactory ->
beanFactory.getBean(RsaKeyConversionServicePostProcessor.class)
.setResourceLoader(new CustomResourceLoader());
}
```
Specify your key's location:
```yaml
key.location: hfds://my-key.pub
```
And then autowire the value:
```java
@Value("${key.location}")
RSAPublicKey key;
```
[[oauth2resourceserver-jwt-decoder-public-key-builder]]
==== Using a Builder
To wire an `RSAPublicKey` directly, you can simply use the appropriate `NimbusJwtDecoder` builder, like so:
```java
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withPublicKey(this.key).build();
}
```
[[oauth2resourceserver-jwt-decoder-secret-key]]
=== Trusting a Single Symmetric Key
Using a single symmetric key is also simple.
You can simply load in your `SecretKey` and use the appropriate `NimbusJwtDecoder` builder, like so:
```java
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withSecretKey(this.key).build();
}
```
[[oauth2resourceserver-jwt-authorization]]
=== Configuring Authorization
@ -690,7 +841,7 @@ Converter<Jwt, AbstractAuthenticationToken> grantedAuthoritiesExtractor() {
```
which is responsible for converting a `Jwt` into an `Authentication`.
As part of its configuration, we can supply a subsidiary converter to go from `Jwt` to a `Collection` of `GrantedAuthority`s.
As part of its configuration, we can supply a subsidiary converter to go from `Jwt` to a `Collection` of granted authorities.
That final converter might be something like `GrantedAuthoritiesExtractor` below: