Java – Spring security oauth2 client

javaspring-security

I've setup an OAuth2 server with spring security. I want to write client application to use this oauth server with spring security without protecting any resource. Means I just want to run oauth2 from client side with spring security 3.1. I have written the following configuration but it asks for credentials before redirecting to oauth2 server authorize page. But I want to redirect user to oauth2 server authorization page before asking any credentials from client side. I am using following configuration

<http auto-config='true' xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/product/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER" />
</http>

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

<!--apply the oauth client context -->
<oauth:client id="oauth2ClientFilter" />


<oauth:resource id="fooClient" type="authorization_code"
    client-id="foo" client-secret="secret" access-token-uri="${accessTokenUri}"
    user-authorization-uri="${userAuthorizationUri}" scope="read" />


 <bean id="dService" class="com.abc.service.DServiceImpl">
    <property name="dURL" value="${dURL}"></property>
    <property name="dRestTemplate">
        <oauth:rest-template resource="fooClient" />
    </property>

 </bean>

So i just want /product url should access oauth2 server. Rest of the URL mapping should work without this.
And User should be anonymous for client ( No need to show login from on client side).

But When I run my application "http://localhost/client-sample/product/1" then it shows "http://localhost/client-sample/spring_security_login". But I want user should redirect to oaut2 server page.

Best Answer

Spring security prevents anonymous users from acquiring an access token. But if you still want this functionality in your application then you will have to extend org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails class and override isClientOnly() method.

import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;

public class ExtendedBaseOAuth2ProtectedResourceDetails extends
    AuthorizationCodeResourceDetails {

public boolean isClientOnly() {
    return true;
}
}

By default this method returns false. So you have to override this method to return true. Then in your root-context.xml file you have to define oaut2 resource like this.

<bean id="fooClient" class="com.abc.service.ExtendedBaseOAuth2ProtectedResourceDetails">
  <property name="clientId" value="foo"></property>
  <property name="clientSecret" value="secret"></property>
  <property name="accessTokenUri" value="${accessTokenUri}"></property>
  <property name="userAuthorizationUri" value="${userAuthorizationUri}"></property>
  <property name="scope" value="#{{'read','write'}}">   </property>
</bean>

<bean id="dService" class="com.abc.service.DServiceImpl">
  <property name="dURL" value="${dURL}"></property>
  <property name="dRestTemplate">
      <oauth:rest-template resource="fooClient" />
  </property>
</bean>

This will not ask authorization on client side before redirecting the user to the oauth2 provider authorization page.