Spring OAuth2 : tokenInfoUri generates ClassCastException with RFC 7662 endpoint
<p>I'm using Spring Security OAuth2 with tokenInfoUri pointing to a CXF RFC 7662 endpoint implementation.</p>
<p>When calling the tokenInfoUri, Spring generates a
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Collection</p>
<p>The response from RFC 7662 is :</p>
<pre><code>{
   &quot;active&quot;:true,
   &quot;client_id&quot;:&quot;83EQEL8D1OiCIw&quot;,
   &quot;username&quot;:&quot;alice&quot;,
   &quot;token_type&quot;:&quot;Bearer&quot;,
   &quot;scope&quot;:&quot;openid hello.say&quot;,
   &quot;iat&quot;:1470083268,
   &quot;exp&quot;:1470086868
}
</code></pre>
<p>So, scope is deserialized into a String not a Collection.
Spring doesn't seem to handle this RFC (<a href="https://www.rfc-editor.org/rfc/rfc7662#section-2.2" rel="nofollow noreferrer">https://www.rfc-editor.org/rfc/rfc7662#section-2.2</a>).</p>
<p>Last version of DefaultAccessTokenConverter handle String type but it should split the scope String (space separator) to create a Set for RFC7662 compliance.</p>
<p>See <a href="https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java#L154" rel="nofollow noreferrer">https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java#L154</a>.</p>
<p>Should I create an issue ?</p>
<p>Thanks,
Adrian</p>
<p>Here are the full details ;
Spring Security OAuth 2.0.9.
Stacktrace :</p>
<pre><code>java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Collection
    at org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter.extractAuthentication(DefaultAccessTokenConverter.java:124) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
    at org.springframework.security.oauth2.provider.token.RemoteTokenServices.loadAuthentication(RemoteTokenServices.java:115) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:83) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:150) ~[spring-security-oauth2-2.0.9.RELEASE.jar:na]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) ~[spring-security-web-4.0.4.RELEASE.jar:4.0.4.RELEASE]
</code></pre>
<p>Configuration :</p>
<pre><code>security:
  user:
    password: user
  oauth2:
    client:
      clientId: blabli
      clientSecret: blabla
    resource:
      serviceId: ${PREFIX:}resource
      tokenInfoUri: http://localhost:9081/oidc/oauth2/introspect
</code></pre>
<p>Request :</p>
<pre><code>POST /oidc/oauth2/introspect HTTP/1.1
Accept: application/json, application/*+json
Authorization: Basic ODNFUUVMOEQxT2lDSXc6dy1OZHpERnlJaTJadThQUkRmeE9Xdw==
Content-Type: application/x-www-form-urlencoded
User-Agent: Java/1.8.0_91
Host: localhost:9080
Connection: keep-alive
Content-Length: 38
token=faa395452928f5126fc8cf61b66bf0f4
</code></pre>
<p>Response :</p>
<pre><code>{
   &quot;active&quot;:true,
   &quot;client_id&quot;:&quot;83EQEL8D1OiCIw&quot;,
   &quot;username&quot;:&quot;alice&quot;,
   &quot;token_type&quot;:&quot;Bearer&quot;,
   &quot;scope&quot;:&quot;openid hello.say&quot;,
   &quot;iat&quot;:1470083268,
   &quot;exp&quot;:1470086868
}
</code></pre>