7

Can anybody tell me what http GET or POST methods should I sequentially call in order to authorize to my apache cxf web services and get access to resources? I tried to call:

http://localhost:8080/oauth/token?client_id=client1&client_secret=client1&grant_type=password&username=client1&password=client1

and all I can get is token response:

{"access_token":"7186f8b2-9bae-48b6-90c2-033a4476c0fc","token_type":"bearer","refresh_token":"d7fe8cda-812b-4b3e-9ce7-b15067e001e4","expires_in":298653}

but what is the next step after I get this token? How can I authenticate the user and get access to resource in url /resources/MyResource/getMyInfo which requires user with role ROLE_USER ? Thanks.

I have the following servlet config:

<http pattern="/oauth/token" create-session="stateless"
      authentication-manager-ref="authenticationManager"
      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" before="BASIC_AUTH_FILTER"/>
</http>

<http pattern="/resources/**" create-session="never"
      entry-point-ref="oauthAuthenticationEntryPoint"
      xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false"/>
    <intercept-url pattern="/resources/MyResource/getMyInfo" access="ROLE_USER" method="GET"/>
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
    <access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>

<http pattern="/logout" create-session="never"
      entry-point-ref="oauthAuthenticationEntryPoint"
      xmlns="http://www.springframework.org/schema/security">
    <anonymous enabled="false"/>
    <intercept-url pattern="/logout" method="GET"/>
    <sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"/>
    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
    <access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>

<bean id="logoutSuccessHandler" class="demo.oauth2.authentication.security.LogoutImpl">
    <property name="tokenstore" ref="tokenStore"/>
</bean>

<bean id="oauthAuthenticationEntryPoint"
      class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</bean>

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

<bean id="oauthAccessDeniedHandler"
      class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</bean>

<bean id="clientCredentialsTokenEndpointFilter"
      class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <property name="authenticationManager" ref="authenticationManager"/>
</bean>

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

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

<bean id="clientDetails" class="demo.oauth2.authentication.security.ClientDetailsServiceImpl"/>

<authentication-manager id="userAuthenticationManager"
                        xmlns="http://www.springframework.org/schema/security">
    <authentication-provider ref="customUserAuthenticationProvider">
    </authentication-provider>
</authentication-manager>

<bean id="customUserAuthenticationProvider"
      class="demo.oauth2.authentication.security.CustomUserAuthenticationProvider">
</bean>

<oauth:authorization-server user-approval-handler-ref="userApprovalHandler"
        client-details-service-ref="clientDetails" token-services-ref="tokenServices">
    <oauth:authorization-code/>
    <oauth:implicit/>
    <oauth:refresh-token/>
    <oauth:client-credentials />
    <oauth:password authentication-manager-ref="authenticationManager"/>
</oauth:authorization-server>

<oauth:resource-server id="resourceServerFilter"
                       resource-id="springsec" token-services-ref="tokenServices"/>

<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="accessTokenValiditySeconds" value="300000"/>
    <property name="clientDetailsService" ref="clientDetails"/>
</bean>

<bean id="userApprovalHandler"
      class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
    <property name="tokenServices" ref="tokenServices" />
</bean>

<bean id="MyResource" class="demo.oauth2.authentication.resources.MyResource"/>

and web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"
         version="2.5">
    <display-name>Spring Secure REST</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-servlet.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>contextAttribute</param-name>
            <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>REST Service</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>demo.oauth2.authentication.resources</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>REST Service</servlet-name>
        <url-pattern>/resources/*</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

UPDATED: Found working sample here http://software.aurorasolutions.org/how-to-oauth-2-0-with-spring-security-2/ maybe will be useful for those who have similiar problem

Shendor
  • 749
  • 2
  • 11
  • 18

1 Answers1

5

You first need to create an OAuth2AccessToken which you can then use to build an OAuth2RestTemplate which can then be used perform authenticated GET, POST calls.

Here is an example of how you might setup an OAuth2RestTemplate:

ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider();
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setClientAuthenticationScheme(AuthenticationScheme.form);
resource.setAccessTokenUri("accessTokenURI");
resource.setClientId("clientId");
resource.setGrantType("password");
resource.setClientSecret("clientSecret");
resource.setUsername("userName");
resource.setPassword("password");
OAuth2AccessToken accessToken = provider.obtainAccessToken(getResource(), new DefaultAccessTokenRequest());
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(getResource(), new DefaultOAuth2ClientContext(accessToken));
jcmwright80
  • 2,599
  • 1
  • 13
  • 15
  • Sry, I'm not very good in spring security. Could you please describe full process: Where do I need to paste this code? How to configure it in spring-security context xml configuration? What URL should I use in order to authenticate an user? – Shendor Mar 31 '14 at 17:00
  • How are you intending your rest api to be accessed? If you have a java client application then the code I have provided is an example of how to get an authenticated OAuth token from your service which it builds an OAuthRestTemplate using so that all subsequent requests pass with it the OAuth token which should allow it to access your protected resources. – jcmwright80 Mar 31 '14 at 18:51
  • If you just want to hit your service via the browser then you will have to pass the oauth token string that is returned from your original request along with all subsequent URLs you try to access. The authentication of the user is done in the first call to the service to get the oauth token if the user did not successfully authenticate you wouldn't have received an access token in the response. – jcmwright80 Mar 31 '14 at 18:56
  • I intend to use 2 clients: java spring mvc and .net, so that's why I need all necessary URLs to make http requests in order to authenticate and get access to resources. – Shendor Mar 31 '14 at 19:16
  • "you will have to pass the oauth token string that is returned from your original request along with all subsequent URLs you try to access" --- I have a lot of URL (in production, not in this sample app) and to pass the token to every url doesn't work for me. – Shendor Mar 31 '14 at 19:21
  • Maybe I didn't explain very well so I'll try again. The whole point of oauth is that you authenticate once to get a trusted token which can then be used to prove who you are during all subsequent http requests. In order for this to work you will need to pass the oauth token either in the header or body of a request to a protected url, the url's themselves do not need to change you just have to pass additional data in your request. If this is not what you want then oauth may not be for you. I am not a .Net user so I can't give you a .Net version of my example but a quick google should find some – jcmwright80 Mar 31 '14 at 19:40
  • I just forgot to ask another thing - what's the purpose of /oauth/authorize http request and in what case should I use it? – Shendor Apr 01 '14 at 09:57
  • Are you asking when you should use oauth in general or just a specific /oauth/authorize url? – jcmwright80 Apr 01 '14 at 13:43
  • 1
    I'm asking when I should use just a specific /oauth/authorize url? – Shendor Apr 02 '14 at 06:52