I am trying to integrate Oauth2 with Spring for securing my Restful services in my application. The issue that I am facing is that as soon as I pass the valid client id to get the resfresh/access token, the application redirects to the url with a 404 Response instead of returning the access token without considering the username, password parameters. The Url that is being used is as follows:
For a URL with an invalid client id (e.g. http://localhost:8080/oauthSample/oauth/token?grant_type=password&client_id=test&username=user&password=password) the response returned is
<oauth>
<error_description>No client with requested id: test</error_description>
<error>unauthorized</error>
</oauth>
The security applicationContext.xml is as follows:
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<!-- SPRING OAUTH IMPLICIT SECURTY CONFIG START -->
<!-- Definition of the Authentication Service -->
<http pattern="/oauth/token" create-session="stateless"
xmlns="http://www.springframework.org/schema/security"
authentication-manager-ref="clientAuthenticationManager">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<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"/>
</http>
<!-- Protected resources -->
<http pattern="/services/**"
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="/services/**" 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="dstest"/>
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="dstest/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>
<!-- Authentication in config file -->
<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>
<user-service id="userDetailsService">
<user name="admin" password="password" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!-- Token Store -->
<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"/>
<!-- <property name="accessTokenValiditySeconds" value="100"/> -->
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices"/>
</bean>
<!-- 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="dstest"
token-services-ref="tokenServices"/>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="testabc"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="30"
refresh-token-validity="600"/>
</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"/>
<!-- SPRING OAUTH IMPLICIT SECURTY CONFIG END -->
</beans>
The eclipse console logs (if required) are as follows:
2015-05-11 17:47:40,315 [http-bio-8080-exec-6] DEBUG (AntPathRequestMatcher.java:103) Ð Checking match of request : '/oauth/token'; against '/oauth/token'
2015-05-11 17:47:40,315 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:318) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password at position 1 of 6 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-05-11 17:47:40,315 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:318) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password at position 2 of 6 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:318) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password at position 3 of 6 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AbstractAuthenticationProcessingFilter.java:188) Ð Request is to process authentication
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (ProviderManager.java:152) Ð Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AbstractAuthenticationProcessingFilter.java:311) Ð Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@a2dfd9fc: Principal: org.springframework.security.core.userdetails.User@ab371290: Username: testabc; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_CLIENT,ROLE_TRUSTED_CLIENT; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_CLIENT, ROLE_TRUSTED_CLIENT
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:318) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password at position 4 of 6 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:318) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password at position 5 of 6 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:318) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password at position 6 of 6 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AntPathRequestMatcher.java:103) Ð Checking match of request : '/oauth/token'; against '/oauth/token'
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AbstractSecurityInterceptor.java:193) Ð Secure object: FilterInvocation: URL: /oauth/token?grant_type=password&client_id=testabc&username=user&password=password; Attributes: [IS_AUTHENTICATED_FULLY]
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AbstractSecurityInterceptor.java:298) Ð Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@a2dfd9fc: Principal: org.springframework.security.core.userdetails.User@ab371290: Username: testabc; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_CLIENT,ROLE_TRUSTED_CLIENT; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_CLIENT, ROLE_TRUSTED_CLIENT
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AffirmativeBased.java:65) Ð Voter: org.springframework.security.access.vote.RoleVoter@1838b82, returned: 0
2015-05-11 17:47:40,316 [http-bio-8080-exec-6] DEBUG (AffirmativeBased.java:65) Ð Voter: org.springframework.security.access.vote.AuthenticatedVoter@13c2982, returned: 1
2015-05-11 17:47:40,317 [http-bio-8080-exec-6] DEBUG (AbstractSecurityInterceptor.java:214) Ð Authorization successful
2015-05-11 17:47:40,317 [http-bio-8080-exec-6] DEBUG (AbstractSecurityInterceptor.java:226) Ð RunAsManager did not change Authentication object
2015-05-11 17:47:40,317 [http-bio-8080-exec-6] DEBUG (FilterChainProxy.java:304) Ð /oauth/token?grant_type=password&client_id=testabc&username=user&password=password reached end of additional filter chain; proceeding with original chain
2015-05-11 17:47:40,318 [http-bio-8080-exec-6] DEBUG (ExceptionTranslationFilter.java:115) Ð Chain processed normally
2015-05-11 17:47:40,318 [http-bio-8080-exec-6] DEBUG (SecurityContextPersistenceFilter.java:97) Ð SecurityContextHolder now cleared, as request processing completed
The environment that I am using is as follows:
1. Spring 3.1.0 Release
2. Oauth2 1.0.5 Release
3. Eclipse Luna
4. Maven
5. Apache tomcat 7.0.61
Are there any changes requried with respect to enabling user based authentication after the client is authenticated ?