I would like to implement OAuth 2.0 for my Spring 3.1 and RESTEasy project. The project is a JSON based REST service. I use Spring Security 3.1 and spring-security-oauth2 version 1.0.0.RC2 (which should be the latest). So far I have the spring security setup with default settings. I also have very basic (default) configuration for OAuth 2.0.
I used the REST service before, it works perfect. The Spring security also seems to work just fine. I am redirected to a login page if I open a link to my REST service. After logging in I can make REST calls that give the expected result.
When I open het urls localhost:8080/tools-service/oauth/token or localhost:8080/tools-service/oauth/error, to test the OAuth, I get an error 500.
The following error is show when I access /oauth/token. The error for /oauth/error is simular.
HTTP Status 500 - No adapter for handler [public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(java.security.Principal,java.lang.String,java.util.Map)]: Does your handler implement a supported interface like Controller?
If I am correct this implies that there is an error in the TokenEndpoint.getAccessToken function? Since that class is part of the Spring framework (and I looked up the code, which looks fine) I don't think the problem is actually related to those classes. Which leaves me clueless.
Now I would like to know why this happens and how I can solve this. I considered the fact that I, maybe, am not allowed to visit those URL's in a browser. However if I try the same with Sparklr2 (the Spring OAuth 2.0 sample application) I get an XML message (for /oauth2/token) and an error page (for /oauth2/error), which is as expected.
Any help or tip would be greatly be appreciated.
Security related snippet from web.xml:
<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
My application context loads the following security-config.xml file I created:
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/security
                        http://www.springframework.org/schema/security/spring-security-3.1.xsd
                        http://www.springframework.org/schema/security/oauth2
                        http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
    <sec:http auto-config="true">
        <sec:intercept-url pattern="/**" access="ROLE_USER" />
    </sec:http>
    <sec:authentication-manager>
        <sec:authentication-provider>
            <sec:user-service>
                <sec:user name="user1" password="test123" authorities="ROLE_USER" />
                <sec:user name="user2" password="hello123" authorities="ROLE_USER" />
            </sec:user-service>
        </sec:authentication-provider>
    </sec:authentication-manager>
    <sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
        <sec:expression-handler ref="oauthExpressionHandler" />
    </sec:global-method-security>
    <bean id="clientDetailsService" class="be.collectortools.rest.service.security.CollectorDetailsServiceImpl" />
    <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
    <bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
        <property name="tokenStore" ref="tokenStore" />
        <property name="supportRefreshToken" value="true" />
        <property name="clientDetailsService" ref="clientDetailsService"/>
    </bean>
    <oauth:authorization-server
            client-details-service-ref="clientDetailsService"
            token-services-ref="tokenServices">
        <oauth:authorization-code />
        <oauth:implicit />
        <oauth:refresh-token />
        <oauth:client-credentials />
        <oauth:password />
    </oauth:authorization-server>
    <oauth:expression-handler id="oauthExpressionHandler" />
</beans>
The CollectorClientDetails implementation is only dummy code:
@Service
public class CollectorDetailsServiceImpl implements ClientDetailsService {
    @Resource
    private CollectorClientDetailsRepository collectorClientDetailsRepository;
    @Override
    public ClientDetails loadClientByClientId(final String clientId) throws OAuth2Exception {
        CollectorClientDetails dummyClient = new CollectorClientDetails();
        dummyClient.setClientId(clientId);
        return dummyClient;
    }
}
 
    