Announcement Announcement Module
Collapse
No announcement yet.
Not getting refresh token back from service Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Not getting refresh token back from service

    Hi,
    I am calling a REST based web service which is Oauth2 protected. client is a simple Java standalone client(which uses RestTemplate). Below is the calling code and configuration. I use the /oauth/token url to get the token.
    Grant types for my client are set as 'client_credentials,refresh_token' in DB.
    When I try to get the refresh token from the token sent back I am seeing that it is null. I am seeing that refresh token is getting written in the DB tables -oauth_access_token, oauth_refresh_token by the service. Please advice where it is getting lost. Am I missing any config here ?
    Code:
    Service side config for Spring-security and Oauth :
    
    <?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: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-1.0.xsd
    		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
    	<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" />
    		<access-denied-handler ref="oauthAccessDeniedHandler" />
    	</http>
    
    	
    
    	<!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling 
    		separately. This isn't mandatory, but it makes it easier to control the behaviour. -->
    	<http pattern="/ws/claims/**" 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="/ws/claims/**" access="ROLE_CLIENT,SCOPE_READ" />
    		<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="claimhistory" />
    	</bean>
    
    	<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    		<property name="realmName" value="claimhistory/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" />
    			</list>
    		</constructor-arg>
    	</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="tokenStore" class="org.springframework.security.oauth2.provider.token.JdbcTokenStore">
    		 <constructor-arg index="0"><ref bean="dataSource"/></constructor-arg>
    	</bean>
    
    	<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>
    
    	<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="claimhistory" token-services-ref="tokenServices" />
    		 
    	<bean id="clientDetails" class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">
    		<constructor-arg index="0"><ref bean="dataSource"/></constructor-arg>
    	</bean>
    
    	<mvc:annotation-driven />
    
    	<mvc:default-servlet-handler />
    
    	<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" />
    
    	<!--Basic application beans. -->
    	<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    		<property name="mediaTypes">
    			<map>
    				<entry key="json" value="application/json" />
    			</map>
    		</property>
    		<property name="viewResolvers">
    			<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    				<property name="prefix" value="/WEB-INF/jsp/"></property>
    				<property name="suffix" value=".jsp"></property>
    			</bean>
    		</property>
    		<property name="defaultViews">
    			<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
    				<property name="extractValueFromSingleKeyModel" value="true" />
    			</bean>
    		</property>
    	</bean>
    
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    		<property name="url" value="jdbc:oracle:thin:@sla740q1.unix.magellanhealth.com:1521/mpsappdv.magellanhealth.com"/>
    		<property name="username" value="liferayAppUserQ"/>
    		<property name="password" value="W3lc0m301"/>
    	</bean>
    
    </beans>
    Code:
    //Client calling code : 
    ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
    		resource.setAccessTokenUri(claimHistoryTokenUrl);
    		resource.setClientId("my-client-with-secret"); //my-client-with-registered-redirect
    		resource.setId("claimhistory");
    		resource.setScope(Arrays.asList("read"));
    		resource.setClientSecret("ak_secret");
    		System.out.println("is client only -- > " + resource.isClientOnly());	
    		OAuth2RestTemplate template2 = new OAuth2RestTemplate(resource);
    		OAuth2AccessToken oldToken = template2.getAccessToken();
    	
    		System.out.println("Token value ->"+oldToken.getValue());
    		System.out.println("Token type ->"+oldToken.getTokenType());
                     //refresh token is null here
    		System.out.println("refresh token -- > " + oldToken.getRefreshToken().getValue());

  • #2
    The spec says that client credentials are not allowed to get a refresh token (that's a quote from a comment in the token granter). It's hard to see why you'd need it, since by definition you trust a client that can get a token this way and wouldn't expect it to leak access tokens.

    Comment


    • #3
      Ok. So then I will set up a validity for access token. Once that expires , I will send a new request for getting the access token.
      Does that sound correct ?

      Comment


      • #4
        Sounds perfectly valid to me. If you use Spring OAuth as a client you should get the new token for free next time you access the resource and the old token has expired.

        Comment

        Working...
        X