Search code examples
spring-securityoauth-2.0jacksonresttemplate

How to change MediaType for MappingJacksonHttpMessageConverter in OAuth2RestTemplate


I have an application that is using Spring Source OAuth2 as s client to retrieve user data from a resource server and create a local user. I keep getting the error when the OAuth2ClientContextFilter tries to retrieve the token:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [org.springframework.security.oauth2.common.OAuth2AccessToken] and content type [application/x-javascript;charset=utf-8]

I understand the default MediaType is 'application/json' so I tried to customize the MappingJacksonHttpMessageConverter like this:

<bean id="jacksonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <bean class="org.springframework.http.MediaType">
                    <constructor-arg value="application"/>
                    <constructor-arg value="x-javascript"/>
                    <constructor-arg value="UTF-8"/>
                </bean>
            </list>
     </property>
</bean>

I also tried the 'ALL' constructor arg that is supposed to support */* content types but no luck. See http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/http/MediaType.html

Other important info is that I am using an all XML configuration right now. I just upgraded our 2.5 app to 3.1.1. I'm using OAuth2RestTemplate in a spring security PRE_AUTH filter, not in a controller. So I'm not using annotations to map the rest calls. I've tried adding <context:annotation-config/> but that didn't make a difference.

I'm simply calling my OAuth service bean from my custom AbstractPreAuthenticatedProcessingFilter. When the service bean tries to execute the rest call for user data, an exception is thrown, triggering the OAuth2ClientContextFilter which attempts to retrieve the token. Here's my OAuth2 service bean config:

<bean id="reprintsOauthService" class="com.coral.user.ReprintsOauthService">
    <property name="reprintsUserInfoUrl" value="https://www.demo.com/api/userinfo.ashx" />
    <property name="reprintsRestTemplate">
        <bean class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
            <constructor-arg ref="reprintsResource"/>
            <property name="messageConverters">
                <list>
                   <ref bean="jacksonConverter"/>
                </list>
            </property>
        </bean>
    </property>
</bean> 

Am I missing something? Why doesn't Jackson map the response?


Solution

  • Fixed! The problem was that the OAuth2RestTemplate isn't used for token retrieval. So I had to customize the org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport and add the MappingJacksonHttpMessageConverter to the existing method like this:

      public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        this.messageConverters = new ArrayList<HttpMessageConverter<?>>(messageConverters);
        this.messageConverters.add(new FormOAuth2AccessTokenMessageConverter());
        this.messageConverters.add(new FormOAuth2ExceptionHttpMessageConverter());
    
        MappingJacksonHttpMessageConverter jackson = new MappingJacksonHttpMessageConverter();
        List<MediaType> mediaTypes = new ArrayList<MediaType>();
        mediaTypes.add(new MediaType("application", "x-javascript"));
        jackson.setSupportedMediaTypes(mediaTypes);
        this.messageConverters.add(jackson);
    
        if(logger.isDebugEnabled())
        {
            logger.debug("*** Added custom media type 'application/x-javascript' to the Jackson converter");
        }
    }