When creating a resource server to protect my api endpoints in spring boot I am using spring-boot-starter-oauth2-resource-server and it does not try to pull back the claims from the userinfo endpoint on the authentication server. I am wondering if this is expected behavior and if so should I be using another library to setup spring security for my resource server? It appears debugging that this module pulls in the info from the well-known and should be able to easily know the userinfo endpoint.
This is the current dependencies that I am using maybe I am just missing some module that I am not aware of.
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>openid-resource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>openid-resource</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
NatFar's answer is right on the money, but I thought I'd add some color that I couldn't fit into a comment.
Indeed, Resource Server is about authorization, but the API provides hooks for you to be able to customize this, calling a userinfo endpoint being among them.
As of Spring Security 5.1:
@Override
protected void configure(HttpSecurity http) {
http
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(new MyConverter());
}
private static class MyConverter
implements Converter<Jwt, AbstractAuthenticationToken> {
@Override
public AbstractAuthenticationToken convert(Jwt jwt) {
// invoke the userinfo endpoint
// construct an Authentication statement from the response
}
}
Spring Security 5.1 only supports JWT, however in Spring Security 5.2 (which GAs in a couple of weeks) it supports opaque tokens as well. It also generalizes the representation a bit:
@Override
protected void configure(HttpSecurity http) {
http
.oauth2ResourceServer()
.opaqueToken()
.introspector(new MyIntrospector());
}
private static class MyIntrospector implements OpaqueTokenIntrospector {
@Override
public OAuth2AuthenticatedPrincipal introspect(String token) {
// invoke the userinfo endpoint
// construct an OAuth2AuthenticatedPrincipal from the response
}
}
I've added a ticket to get documentation added around your usecase; however, the JWT-introspection example that's already there is fairly close.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With