Spring Security OAuth 2.0存在一個問題。Spring Security Oauth - 發送令牌請求時需要基本訪問認證
有彈簧安全的基本配置,從採樣:
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<http pattern="/path/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/path/*" access="ROLE_USER" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="path" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="path/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<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>
<bean id="oauthAuthenticationProvider" class="my.package.OAuthAuthenticationProvider" xmlns="http://www.springframework.org/schema/beans" />
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="oauthAuthenticationProvider" />
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<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="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<!-- authorization-server aka AuthorizationServerTokenServices is an interface
that defines everything necessary for token management -->
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<!-- ClientsDeailsService: Entry Point to clients database (given is in
memory implementation) -->
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="the_client"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_USER" scope="read,write,trust" secret="secret" />
<oauth:client client-id="my-trusted-client-with-secret"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="somesecret" authorities="ROLE_USER" />
</oauth:client-details-service>
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
它的工作原理,在我的web.xml文件看起來是這樣的:
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml</param-value>
</context-param>
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
<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>
...
<servlet>
<servlet-name>Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
...
<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
但在這種情況下,系統的「舊部分」不起作用。 所以我必須要改變調度servlet映射:
<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/somepath/*</url-pattern>
</servlet-mapping>
現在舊的一部分作品,但不是的Oauth春季安全。我試過兩種網址模式:
<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/somepath/*</url-pattern>
<url-pattern>/*</url-pattern>
</servlet-mapping>
然後oauth的作品,舊的部分沒有。
我做了一個嘗試和改變:
<http pattern="/somepath/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/somepath/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
而現在它的工作原理是這樣的:
我訪問地址(工作前):
網絡瀏覽器要求登錄和密碼(基本訪問認證)。
我需要在登錄字段和密碼字段中輸入client-id。
生成對oauth的請求,然後調用my.package.OAuthAuthenticationProvider中的身份驗證方法。
我應該更改哪些以避免此基本身份驗證提示?
感謝您的回覆。 我在另一個項目中使用spring oauth。我必須使用默認的servlet映射,但有可能(應用程序不能在生產環境中運行:))。沒有連接到ContextLoaderListener的spring-security配置文件,spring-security將不會啓動。 但在第二個應用程序的情況下,基本身份驗證沒有要求client_id和secret,並通過GET請求參數傳遞足以進行身份驗證...同樣的情況發生在這裏,當我將Dispatcher Servlet映射更改爲默認一。 –
如果沒有作爲根環境加載Spring Security,「不會啓動」並不正確(請查看oauth示例中的反例)。我想我記得你沒有啓用的設置,你需要一個非默認的servlet映射 - auth和token endpoint urls必須被明確設置。我需要再看看更多的細節(明天),看看我能否用更多的信息更新答案,但也許這會讓你開始。 –
再次感謝您的幫助。 現在我使用POST方法和其他方式發送基本身份驗證憑據,它似乎工作正常。 我應該如何設置這個「POST-only」驗證器? –