spring-security - oauth2 提供程序端点的处理程序错误没有适配器

标签 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(应该是最新的)。到目前为止,我已经使用默认设置进行了 spring 安全设置。我还有非常基本的(默认)OAuth 2.0 配置。

我之前用过 REST 服务,效果很好。 Spring 安全性似乎也工作得很好。如果我打开指向我的 REST 服务的链接,我将被重定向到登录页面。登录后,我可以进行 REST 调用以提供预期结果。

当我打开网址时 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 框架的一部分(并且我查找了代码,看起来不错)我认为问题实际上与这些类无关。这让我毫 headless 绪。

现在我想知道为什么会发生这种情况以及如何解决这个问题。
我考虑过我可能不允许在浏览器中访问这些 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;
    }

}

最佳答案

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

在这里我发现banifou也有同样的问题。戴夫·赛尔 (Dave Syer) 是这样回答问题的:

It looks like you removed the <mvc:annnotation-driven/> from the vanilla sparklr. I think if you put that back in the handler adapter will be defined for you.



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-driven ,
    default-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>
    

    关于spring-security - oauth2 提供程序端点的处理程序错误没有适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12745739/

    相关文章:

    java - 找不到具有 starter-security 依赖项的 springframework.security 包?

    java - spring-security 错误登录的用户

    asp.net-mvc - 使用 facebook SDK 登录 MVC5 应用程序时出现错误(error=access_denied)

    rest - application/* Content-Type 和 charset 属性

    java - org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure : Could not find MessageBodyWriter for response object of type

    java - Spring Security 循环 bean 依赖

    java - 使用 Spring Security 的访问被拒绝页面不起作用

    node.js - 23andMe API 错误 : 'No grant_type provided.' 'invalid_request' OAuth2

    java - 无需浏览器的 Google OAuth 2.0 登录

    java - RESTEasy 404 未找到