1

我使用jersey作为 RESTFul 网络服务器。(jersey-server 1.8) 与 spring (3.2.0.RELEASE) 和休眠。我的端点使用带有 2 条腿 oAuth 1.0a (spring-security-oauth 1.0.0.M4) 的 spring-security (3.1.3.RELEASE) 进行保护

一切都按预期工作,并且固定工作。在我的 ConsumerDetailsS​​erviceImpl(实现 ConsumerDetailsS​​ervice、UserDetailsS​​ervice、AuthenticationProvider)中,我抛出了不同的异常(现在都是 OAuthException 形式,但我想添加自己的自定义异常)

但是,无论我尝试什么,我都无法按照我想要的方式自定义不同的身份验证和拒绝访问异常,我总是得到默认的 401 页面

我的 API 被同意总是返回一个 json 响应对象,所以我需要捕获这些异常并显示 401 页面,其中包含 json

我的安全.xml

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


<!-- Authentication beans -->
<bean name="consumerDetailsService" class="com.securitytest.core.services.impl.ConsumerDetailsServiceImpl" />
<bean name="oauthProcessingFilterEntryPoint" class="org.springframework.security.oauth.provider.OAuthProcessingFilterEntryPoint" />
<bean id="oAuthAuthenticationHandler" class="com.securitytest.core.security.CustomOAuthAuthenticationHandler" />

<security:http auto-config="true" use-expressions="true" entry-point-ref="oauthProcessingFilterEntryPoint" >
    <security:intercept-url pattern="/rest/secured/**" access="isAuthenticated()" />
    <security:intercept-url pattern="/rest/unsecured/**" access="permitAll" />
    <security:intercept-url pattern="/rest/**" access="isAuthenticated()" />
    <security:form-login login-page='/login' default-target-url="/home"  authentication-failure-handler-ref="authenticationFailureHandler"/>
    <security:access-denied-handler ref="accessDeniedHandler" />
</security:http>

<bean id="accessDeniedHandler" class="com.securitytest.core.security.CustomoauthAccessDeniedHandler" />
  <!-- this was just a test, it didn't work obviously -->  
<bean id="authenticationFailureHandler"              class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
    <property name="exceptionMappings">
        <props>
            <prop key="org.springframework.security.authentication.BadCredentialsException">/login/badCredentials</prop>
            <prop key="org.springframework.security.authentication.CredentialsExpiredException">/login/credentialsExpired</prop>
            <prop key="org.springframework.security.authentication.LockedException">/login/accountLocked</prop>
            <prop key="org.springframework.security.authentication.DisabledException">/login/accountDisabled</prop>
        </props>
    </property>
</bean>

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="consumerDetailsService" />
</security:authentication-manager>

<bean id="nonceServices" class="org.springframework.security.oauth.provider.nonce.InMemoryNonceServices" />

<oauth:provider 
        auth-handler-ref="oAuthAuthenticationHandler" 
        consumer-details-service-ref="consumerDetailsService" 
        nonce-services-ref="nonceServices" 
        token-services-ref="tokenServices"
        require10a="true"

        />
<oauth:token-services id="tokenServices" />

我试过的东西

  1. 更改 exceptionTranslationFilter -> 文档不允许
  2. 添加自定义 access-denied-handler 和 authentication-failure-handler-ref

    <security:http auto-config="true" use-expressions="true" entry-point-ref="oauthProcessingFilterEntryPoint" >
       <security:intercept-url pattern="/rest/secured/**" access="isAuthenticated()" />
       <security:intercept-url pattern="/rest/unsecured/**" access="permitAll" />
       <security:intercept-url pattern="/rest/**" access="isAuthenticated()" />
       <security:form-login login-page='/login' default-target-url="/home"  authentication-failure-handler-ref="authenticationFailureHandler"/>
    
       <security:access-denied-handler ref="accessDeniedHandler" />
    </security:http>
    

    -> 这被 spring-security/oauth 公然忽略

  3. 在 EXCEPTION_TRANSLATION_FILTER 之后添加自定义过滤器

    <security:custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="myFilter" />
    

    MyFilter 只是实现“javax.servlet.Filter”。-> 它进入doFilter,但我不知道如何处理它(我看不到抛出了哪个异常,如果有的话)。

任何帮助表示赞赏!

4

1 回答 1

0

我回答这个问题已经很晚了,您可能已经解决或转向其他选择。但是,我最近潜入了 Oauth 并遇到了类似的问题并设法解决了它。分享给其他人作为参考。

我使用 Oauth 的 MediaTypeAwareAccessDeniedHandler 和 MediaTypeAwareAuthenticationEntryPoint 进行错误处理。根据文档,它默认为 401 错误页面。但是,从源代码来看,错误响应内容类型取决于请求 Accept-Type。但是要求客户端始终将 Accept-Type 发送为 application/json 就像要求 fox 保护母鸡一样。

好消息是响应类型支持 setter 注入。如此简单的解决方案是覆盖默认值并注入响应属性以始终发送 JSON 响应,而不管 Accept-Type

<bean id="accessDeniedHandler" class="org.springframework.security.oauth2.provider.error.MediaTypeAwareAccessDeniedHandle"/>
   <property name="responses">
     <map> 
       <entry key="*/*" value="{error:&quot;%s&quot;}"></entry>
     </map>
   </property>
 </bean>
于 2013-10-06T13:16:41.967 回答