2015-03-31 116 views
1

使用:可以訪問春天的oauth2保護資源而不訪問令牌

  • 彈簧安全3.2.5
  • 彈簧安全的OAuth 2.0.7(的oauth2)
  • grant_type:authentication_code

我沒有問題得到authentication_code和訪問令牌。 我遇到的問題是,如果我調用一個「受保護」的資源,我可以根本不訪問任何令牌。這裏是「不真正保護」資源的安全配置:

<security:http pattern="/api/user/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" 
        access-decision-manager-ref="accessDecisionManager"> 
    <security:anonymous enabled="false" /> 
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" /> 
    <security:custom-filter ref="userResourceServer" before="PRE_AUTH_FILTER" /> 
    <security:access-denied-handler ref="oauthAccessDeniedHandler" /> 
</security:http> 

的Oauth2AuthenticationProcessingFilter是說

沒有令牌的請求,將繼續鏈。

我發現this other post至極似乎說明了同樣的問題,但提出的解決方案是增加<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />,至極我已經有了。

此外,艱難也許不相關,對受保護資源的請求會收到標頭,定義一個jsessionid。因爲我指定了create-session="never",所以對我來說這似乎不正常。

因爲我使用OAuth2AccessDeniedHandler,我預計未經授權調用此資源返回403。

有人可以幫助我嗎?

請注意,我非常確定這個安全配置正在踢,因爲在我的受保護資源(一個spring-mvc控制器)中,SecurityContextHolder.getContext().getAuthentication()返回null。如果我完全禁用上述安全配置,則同一行將返回匿名身份驗證。

編輯:詳細的配置信息。

首先我令牌enpoint配置:

<security:http pattern="/api/oauth/token" 
       create-session="stateless" 
       authentication-manager-ref="clientAuthenticationManager"> 
    <security:intercept-url pattern="/api/oauth/token" 
          access="IS_AUTHENTICATED_FULLY" /> 
    <security:anonymous enabled="false" /> 
    <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" /> 
    <security:access-denied-handler ref="oauthAccessDeniedHandler" /> 
    </security:http> 

那麼資源端點配置(如在問題之初所示):

<security:http pattern="/api/user/**" 
        create-session="never" 
        entry-point-ref="oauthAuthenticationEntryPoint" 
        access-decision-manager-ref="accessDecisionManager"> 
    <security:anonymous enabled="false" /> 
    <security:intercept-url pattern="/api/user/**" 
          access="IS_AUTHENTICATED_FULLY" /> 
    <security:custom-filter ref="userResourceServer" 
          before="PRE_AUTH_FILTER" /> 
    <security:access-denied-handler ref="oauthAccessDeniedHandler" /> 
    </security:http> 

,然後在「通用」的網址配置:

<security:http name="genericSecurityConfiguration" entry-point-ref="customLoginEntrypoint"> 
    <security:form-login authentication-failure-url="/index.jsp" 
         authentication-success-handler-ref="customAuthenticationSuccessHandler" 
         authentication-failure-handler-ref="customAuthenticationFailureHandler" 
         login-page="/index.jsp" 
         login-processing-url="/solapCore/identification2" 
         username-parameter="username" 
         password-parameter="password" 
         /> 
    <security:session-management invalid-session-url="/index.jsp?invalidSession=true" session-authentication-strategy-ref="sas" /> 
    <security:custom-filter position="LOGOUT_FILTER" ref="logoutFilter"/> 
    <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="monitoringFilter"/> 
    <security:access-denied-handler ref="solapcoreAccessDeniedHandler"/> 
    </security:http> 

相同文件中的其他oauth特定配置:

<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
    <property name="realmName" value="oauth" /> 
    </bean> 

    <bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
    <property name="realmName" value="oauth/client" /> 
    <property name="typeName" value="Basic" /> 
    </bean> 

    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"> 
    <constructor-arg> 
    <list> 
     <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" /> 
     <bean class="org.springframework.security.access.vote.RoleVoter" /> 
     <bean class="org.springframework.security.access.vote.AuthenticatedVoter" /> 
    </list> 
    </constructor-arg> 
    </bean> 

    <security:authentication-manager id="clientAuthenticationManager"> 
    <security:authentication-provider user-service-ref="clientDetailsUserService" /> 
    </security:authentication-manager> 

    <bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> 
    <constructor-arg ref="clientDetails" /> 
    </bean> 
    <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" /> 

    <oauth:authorization-server 
    client-details-service-ref="clientDetails" 
    token-services-ref="tokenServices" 
    user-approval-handler-ref="userApprovalHandler"> 
    <oauth:authorization-code /> 
    </oauth:authorization-server> 

    <oauth:resource-server id="userResourceServer" 
         resource-id="oauth2/user" 
         token-services-ref="tokenServices" /> 

    <oauth:client-details-service id="clientDetails"> 
    <oauth:client client-id="someClientID" 
        authorized-grant-types="authorization_code" 
        authorities="SOME_AUTHORITY" scope="read" secret="secret" /> 
    </oauth:client-details-service> 

<security:global-method-security pre-post-annotations="enabled" proxy-target-class="true"> 
    <security:expression-handler ref="oauthExpressionHandler" /> 
</security:global-method-security> 

<oauth:expression-handler id="oauthExpressionHandler" /> 
<oauth:web-expression-handler id="oauthWebExpressionHandler" /> 

<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.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="clientDetails" /> 
</bean> 

Finaly,我的調度servlet和filterChain配置在web.xml:

回答

0
+0

它與訪問令牌(授權標頭)完美配合。問題是我的資源即使沒有令牌也被調用。 – baraber 2015-03-31 18:06:52

+0

你的web.xml中的url模式是/ api/*。也許你需要從你的安全配置中刪除/ api前綴。 – 2015-04-01 05:21:21

+0

我有其他servlet映射不同,所以我需要縮小調度程序servlet的url模式。但調度程序servlet正在處理請求,所以servlet的url-pattern應該是正確的,否則我會看到404。 – baraber 2015-04-01 12:37:44

0

在配置有問題的部分是<security:http pattern="/api/user/**" ...>

由於 「模式」 屬性設置爲/ API /用戶/ **,你的攔截URL「模式」屬性

<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" /> 

只有具有相同的前綴(/ api/user/**)時纔會有任何效果。

如果你想IS_AUTHENTICATED_FULLY只能使用/ API /用戶/ **模式,那麼攔截的URL應該是

<security:http pattern="/api/user/**" ...> 
    <security:anonymous enabled="false" /> 
    <security:intercept-url pattern="/api/user/**" access="IS_AUTHENTICATED_FULLY" /> 
    <security:custom-filter ref="userResourceServer" before="PRE_AUTH_FILTER" /> 
    <security:access-denied-handler ref="oauthAccessDeniedHandler" /> 
</security:http> 

如果你想申請全面應用該規則,然後這樣的事情應該工作:

<security:http create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" 
        access-decision-manager-ref="accessDecisionManager"> 
    <security:anonymous enabled="false" /> 
    <security:intercept-url pattern="/api/user/**" access="IS_AUTHENTICATED_FULLY" /> 
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" /> 
    <security:custom-filter ref="userResourceServer" before="PRE_AUTH_FILTER" /> 
    <security:access-denied-handler ref="oauthAccessDeniedHandler" /> 
</security:http> 
+0

感謝您試圖幫助我:)問題是我已將「/ **」在攔截url模式,因爲「/ api /用戶/ **」不工作(這是我第一次嘗試)。此外,我沒有在問題中提到它,但我也在/ api/user/**下面有一個通用的元素來捕獲其他網址。起初,我認爲這可能是問題的一部分,但即使沒有通用的元素,問題仍然存在:我可以在沒有任何令牌的情況下訪問資源(也不需要以任何其他方式進行身份驗證)。不過,謝謝你試圖幫助,非常感謝。 – baraber 2015-03-31 19:41:56

+0

你能分享你的完整安全配置文件嗎?很難弄清楚問題的原因是什麼。 – Jigish 2015-03-31 19:56:38

+0

當然。我剛剛添加了它。 – baraber 2015-03-31 20:35:09

0

我發現問題的原因,它是非常具體到我們的應用程序。

在配置的其他地方,我們重寫內置的FilterInvocationSecurityMetadataSource(使用邪惡的豆後期處理器)來添加一個自定義的。這樣可以禁用配置文件中的所有<intercept-url>。我們這樣做是因爲我們將傳統的自定義安全框架遷移到spring-security,並希望將url安全性保留在我們已有的文件中。

感謝所有試圖幫助。