没有适用于oauth2提供程序端点的处理程序错误的适配器

时间:2012-10-05 11:55:04

标签: spring-security oauth-2.0 resteasy oauth-provider

我想为我的Spring 3.1和RESTEasy项目实现OAuth 2.0。该项目是基于JSON的REST服务。我使用Spring Security 3.1和spring-security-oauth2版本1.0.0.RC2(应该是最新版本)。到目前为止,我有弹簧安全设置默认设置。我还有OAuth 2.0的基本(默认)配置。

之前我使用过REST服务,它完美无缺。 Spring安全性似乎也运行得很好。如果我打开到我的REST服务的链接,我将被重定向到登录页面。登录后,我可以进行REST调用以获得预期的结果。

当我打开het网址localhost:8080/tools-service/oauth/tokenlocalhost:8080/tools-service/oauth/error时,为了测试OAuth,我收到错误500。 访问/oauth/token时会显示以下错误。 /oauth/error的错误是类似的。

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?

如果我是正确的,这意味着TokenEndpoint.getAccessToken函数中存在错误?由于该类是Spring框架的一部分(我查找了代码,看起来很好),我不认为问题实际上与这些类有关。这让我一无所知。

现在我想知道为什么会发生这种情况以及如何解决这个问题。 我考虑过,我可能不允许在浏览器中访问这些URL。但是,如果我尝试使用Sparklr2(the Spring OAuth 2.0 sample application),我会得到一条XML消息(对于/ oauth2 / token)和一个错误页面(对于/ oauth2 / error),这是预期的。

非常感谢任何帮助或提示。


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>

我的应用程序上下文加载了我创建的以下security-config.xml文件:

<?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>

CollectorClientDetails实现只是虚拟代码:

@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;
    }

}

1 个答案:

答案 0 :(得分:11)

让这个问题冷却了几天后,我做了一个新的谷歌搜索。这导致我进入Spring Source论坛:http://forum.springsource.org/showthread.php?130684-OAuth2-No-adapter-for-handler-exception

在这里,我发现banifou有同样的问题。 Dave Syer回答了这样的问题:

  

您好像从中删除了<mvc:annnotation-driven/>   香草火花。我想如果你把它放回处理程序适配器   将为您定义。

Spring安全依赖于Spring MVC框架来处理请求和响应。因此,需要包含MVC框架并正确设置Spring安全OAuth才能工作。

解决方案是我在应用程序上下文中添加了2个标记:

  • <mvc:annotation-driven />

使MVC框架准备好处理注释。这使@FrameworkEndpoint正常工作。后一个用于public class TokenEndpoint,它给出了错误500。

  • <mvc:default-servlet-handler />

此处理程序将所有请求转发到默认Servlet。因此,重要的是它按照所有其他URL HandlerMappings的顺序保持最后。如果您使用<mvc:annotation-driven>,就会出现这种情况。 (引自Spring文档。)

可在此处找到更多信息: annotation-drivendefault-servlet-handler

<?xml version='1.0' encoding='UTF-8'?>

<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.1.xsd
                            http://www.springframework.org/schema/mvc
                            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <context:component-scan base-package="be.collectortools.rest"/>
    <context:annotation-config/>

    <mvc:annotation-driven />
    <mvc:default-servlet-handler />

    <import resource="classpath:springmvc-resteasy.xml"/>
    <import resource="mongo-config.xml"/>
    <import resource="security-config.xml"/>

</beans>