2016-05-16 60 views
0

我想实现Oauth2弹簧安全与春天4.1 我发送密码,用户名,client_id和client_secret但仍然收到错误凭据。 我发送请求如下:Oauth2与春投丢坏的凭据

http://localhost:8080/asset-manager/oauth/token?grant_type=password&client_id=restapp&client_secret=restapp&username=ankita&password=ankita

我有以下文件

弹簧security.xml文件

<?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:oauth="http://www.springframework.org/schema/security/oauth2" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd 
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd "> 

<!-- This is default url to get a token from 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="isFullyAuthenticated()" /> 
    <anonymous enabled="false" /> 
    <http-basic entry-point-ref="clientAuthenticationEntryPoint" /> 
    <!-- include this only if you need to authenticate clients via request 
     parameters --> 
    <custom-filter ref="clientCredentialsTokenEndpointFilter" 
     after="BASIC_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
    <csrf disabled="true" /> 
</http> 

<!-- This is where we tells spring security what URL should be protected 
    and what roles have access to them --> 
<http pattern="/api/**" 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="/api/**" access="hasRole('ROLE_USER')" /> 
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
    <csrf disabled="true" /> 
</http> 


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

<bean id="requestFactory" 
    class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory"> 
    <constructor-arg name="clientDetailsService" ref="clientDetails" /> 
</bean> 

<bean id="clientAuthenticationEntryPoint" 
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
    <property name="realmName" value="test/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="authenticationManager" /> 
</bean> 

<bean id="accessDecisionManager" 
    class="org.springframework.security.access.vote.AffirmativeBased" 
    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" /> 
      <bean 
       class="org.springframework.security.web.access.expression.WebExpressionVoter"></bean> 
     </list> 
    </constructor-arg> 
</bean> 


<authentication-manager id="clientAuthenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <authentication-provider user-service-ref="clientDetailsUserService" /> 
</authentication-manager> 

<bean id="authenticationProcessingFilter" 
    class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> 
    <property name="authenticationManager" ref="authenticationManager" /> 
</bean> 
<!-- This is simple authentication manager, with a hardcoded user/password 
    combination. We can replace this with a user defined service to get few users 
    credentials from DB --> 
<authentication-manager alias="authenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <authentication-provider> 
     <user-service> 
      <user name="ankita" password="ankita" authorities="ROLE_USER" /> 
     </user-service> 
    </authentication-provider> 
    <authentication-provider user-service-ref="clientDetailsUserService" /> 

</authentication-manager> 

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


<!-- This defined token store, we have used inmemory tokenstore for now 
    but this can be changed to a user defined one --> 
<bean id="tokenStore" 
    class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" /> 

<!-- This is where we defined token based configurations, token validity 
    and other things --> 
<bean id="tokenServices" 
    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"> 
    <property name="tokenStore" ref="tokenStore" /> 
    <property name="supportRefreshToken" value="true" /> 
    <property name="accessTokenValiditySeconds" value="120" /> 
    <property name="clientDetailsService" ref="clientDetails" /> 
</bean> 

<bean id="userApprovalHandler" 
    class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler"> 
    <property name="tokenStore" ref="tokenStore" /> 
    <property name="clientDetailsService" ref="clientDetails" /> 
    <property name="requestFactory" ref="requestFactory" /> 
</bean> 

<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" /> 

<oauth:client-details-service id="clientDetails"> 
    <!-- client --> 
    <oauth:client client-id="restapp" 
     authorized-grant-types="authorization_code,client_credentials" 
     authorities="ROLE_USER" scope="read,write,trust" secret="secret" /> 

    <oauth:client client-id="restapp" 
     authorized-grant-types="password,authorization_code,refresh_token,implicit" 
     secret="restapp" scope="read,write,trust" authorities="ROLE_USER" /> 

</oauth:client-details-service> 
<bean id="httpSessionSecurityContextRepository" 
    class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'> 
    <property name='allowSessionCreation' value='false' /> 
</bean> 
<bean id="securityContextPersistenceFilter" 
    class="org.springframework.security.web.context.SecurityContextPersistenceFilter"> 
    <constructor-arg ref="httpSessionSecurityContextRepository" /> 
</bean> 
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> 
    <constructor-arg> 
     <list> 
      <sec:filter-chain pattern="/**" 
       filters="securityContextPersistenceFilter" /> 
     </list> 
    </constructor-arg> 
</bean> 
<sec:global-method-security 
    pre-post-annotations="enabled" proxy-target-class="true" 
    authentication-manager-ref="authenticationManager" 
    secured-annotations="enabled"> 
    <!--you could also wire in the expression handler up at the layer of the 
     http filters. See https://jira.springsource.org/browse/SEC-1452 --> 
    <sec:expression-handler ref="oauthExpressionHandler" /> 
</sec:global-method-security> 

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

这是我的pom.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
version="2.5"> 



<servlet> 
    <servlet-name>mvc-dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<servlet-mapping> 
    <servlet-name>mvc-dispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
    /WEB-INF/mvc-dispatcher-servlet.xml,   
     /WEB-INF/spring-security.xml 
     </param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- Spring Security --> 

<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> 
<listener> 
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
</listener> 
<listener> 
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> 
</listener> 

不幸的是,每当我发出请求时,它抛出这个:

{ 
    "error": "invalid_grant", 
    "error_description": "Bad credentials" 
} 

需要帮助!

回答

0

我不得不更改一些spring-security.xml文件中具有更新功能的属性,并且我还根据我的用例覆盖了一些类,如AuthenticationProvider和ClientDetailsS​​ervice,我还使用redis作为我的令牌存储,你可以将它替换成内存令牌存储

我更新了spring-security。xml是:

<?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:oauth="http://www.springframework.org/schema/security/oauth2" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd 
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd 
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd 
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd "> 

<!-- This is default url to get a token from 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="isFullyAuthenticated()" method="POST"/> 
    <intercept-url pattern="/v1/access_token" access="isFullyAuthenticated()" method="POST"/> 
    <anonymous enabled="false" /> 
    <http-basic entry-point-ref="oauthAuthenticationEntryPoint" /> 
    <!-- include this only if you need to authenticate clients via request 
     userService parameters --> 
    <custom-filter ref="clientCredentialsTokenEndpointFilter" 
     after="BASIC_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
    <csrf disabled="true" /> 
</http> 

<!-- This is where we tells spring security what URL should be protected 
    and what roles have access to them --> 
<http pattern="/v1/**" create-session="stateless" 
    entry-point-ref="oauthAuthenticationEntryPoint" 
    access-decision-manager-ref="accessDecisionManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <anonymous enabled="false" /> 
    <intercept-url pattern="/v1/application/register" access="hasRole('ROLE_ADMIN')" /> 
    <intercept-url pattern="/v1/application/{clientId}" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" /> 
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> 
    <access-denied-handler ref="oauthAccessDeniedHandler" /> 
    <csrf disabled="true" /> 
</http> 

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

<bean id="clientAuthenticationEntryPoint" 
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
    <property name="realmName" value="test/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="authenticationManager" /> 
</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" /> 
      <bean 
       class="org.springframework.security.web.access.expression.WebExpressionVoter" /> 
     </list> 
    </constructor-arg> 
</bean> 

<authentication-manager id="clientAuthenticationManager" 
    xmlns="http://www.springframework.org/schema/security"> 
    <!-- <authentication-provider user-service-ref="clientDetailsUserService" 
     /> --> 
    <authentication-provider ref="AuthenticationProvider" /> 
</authentication-manager> 

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

<authentication-manager 
    xmlns="http://www.springframework.org/schema/security" alias="authenticationManager"> 
    <authentication-provider ref="AuthenticationProvider" /> 
</authentication-manager> 

<bean id="AuthenticationProvider" 
    class="com.timeinc.security.biz.client.security.impl.AuthenticationProviderImpl"> 
    <property name="userService" ref="userService"></property> 
</bean> 

<bean id="tokenStore" 
    class="org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore"> 
    <constructor-arg name="connectionFactory" ref="redisConnectionFactory" /> 
</bean> 

<!--create redis connection factory and set db 1 --> 
<bean id="redisConnectionFactory" 
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> 
    <property name="hostName" value="${redisHost}" /> 
    <property name="port" value="${redisPort}" /> 
    <property name="password" value="${redisPassword}" /> 
    <property name="database" value="${redisDatabase}" /> 
</bean> 

<bean id="tokenServices" class="com.timeinc.security.biz.client.security.impl.DefaultTokenServicesImpl"> 
    <property name="tokenStore" ref="tokenStore" /> 
    <property name="supportRefreshToken" value="true" /> 
    <property name="accessTokenValiditySeconds" value="${accessTokenValiditySeconds}" /> 
    <property name="refreshTokenValiditySeconds" value="${refreshTokenValiditySeconds}"></property> 
    <property name="clientDetailsService" ref="clientDetailsService" /> 
</bean> 

<bean id="requestFactory" 
    class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory"> 
    <constructor-arg name="clientDetailsService" ref="clientDetailsService" /> 
</bean> 

<bean id="userApprovalHandler" 
    class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler"> 
    <property name="tokenStore" ref="tokenStore" /> 
    <property name="clientDetailsService" ref="clientDetailsService" /> 
    <property name="requestFactory" ref="requestFactory" /> 
</bean> 

<oauth:authorization-server 
    client-details-service-ref="clientDetailsService" 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" /> 


<bean id="clientDetailsService" class="com.timeinc.security.biz.client.security.impl.ClientDetailsServiceImpl"> 
    <property name="appClient" ref="appClient"></property> 
</bean> 
<bean id="httpSessionSecurityContextRepository" 
    class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'> 
    <property name='allowSessionCreation' value='false' /> 
</bean> 

<bean id="userService" class="com.timeinc.security.biz.client.security.impl.UserDetailsServiceImpl"> 
    <property name="appClient" ref="appClient"></property> 
</bean> 

<bean id="securityContextPersistenceFilter" 
    class="org.springframework.security.web.context.SecurityContextPersistenceFilter"> 
    <constructor-arg ref="httpSessionSecurityContextRepository" /> 
</bean> 
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> 
    <constructor-arg> 
     <list> 
      <sec:filter-chain pattern="/**" 
       filters="securityContextPersistenceFilter" /> 
     </list> 
    </constructor-arg> 
</bean> 
<sec:global-method-security 
    pre-post-annotations="enabled" proxy-target-class="true"> 
    <!--you could also wire in the expression handler up at the layer of the 
     http filters. See https://jira.springsource.org/browse/SEC-1452 --> 
    <sec:expression-handler ref="oauthExpressionHandler" /> 
</sec:global-method-security> 

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

</beans> 
+0

怎么能有人知道哪个配置解决了你的问题? – Stephan

0

您只需要传递用户名,密码(这两个都是用户,而不是客户端),grant_type和client_id请求参数。

您必须使用客户端ID作为用户名和客户端密码作为密码发送授权标头,其中包含BASIC身份验证。

这是你会怎么做,在卷曲例如:

$ curl -u restapp:restapp http://localhost:8080/asset-manager/oauth/token -d grant_type=password -d client_id=restapp 
0

我使用Spring Security 4.0.4升级到4.1.1时,也有类似的问题。

尝试在你的认证管理器bean定义为“ID”改变“别名”:

<authentication-manager id="authenticationManager" 
       xmlns="http://www.springframework.org/schema/security"> 
    <authentication-provider> 
     <user-service> 
      <user name="ankita" password="ankita" authorities="ROLE_USER" /> 
     </user-service> 
    </authentication-provider> 
<authentication-provider user-service-ref="clientDetailsUserService" /> 

我发现,由于某种原因,在自定义的“别名”定义“的AuthenticationManager”不没有得到承认。当我将“别名”更改为“id”时,我的自定义AuthenticationManager再次工作。

我在测试Spring Security 4.1.0时看到了这个问题,所以我不确定Spring Security 4.0.4和4.1.0之间的变化是什么导致了这个问题的发生。

我试图在Spring Security github中搜索发行说明和问题,但找不到与此相关的任何内容。我所知道的是,这个小修补程序为我工作。

希望这会有所帮助。

+0

这并没有解决我的问题,但你可以看看我发布的答案 –

+0

感谢您的建议!我帮助了这些信息。因为这个废话我什么也没有工作,我真的不明白发生了什么事! – Eremite

相关问题