Results 1 to 6 of 6

Thread: Can't get AuthorizationRequest in the AccessConfirmationController

  1. #1
    Join Date
    Mar 2013
    Posts
    3

    Default Can't get AuthorizationRequest in the AccessConfirmationController

    Hi,

    I am building a simple OAuth2 provider using spring-security-oauth 1.0.2.RELEASE. My XML configuration is:
    Code:
    	<http auto-config='true' 
    		xmlns="http://www.springframework.org/schema/security">
    		<intercept-url pattern="/**" access="ROLE_USER" />
    	</http>
    
    	<authentication-manager
    		xmlns="http://www.springframework.org/schema/security">
    		<authentication-provider>
    			<user-service>
    				<user name="a" password="a" authorities="ROLE_USER" />
    			</user-service>
    		</authentication-provider>
    	</authentication-manager>
    
    	<!-- OAuth Provider Configuration -->
    	<oauth2:authorization-server
    		client-details-service-ref="clientDetailsService" token-services-ref="tokenServices"
    		user-approval-handler-ref="userApprovalHandler">
    		<oauth2:authorization-code />
    		<oauth2:implicit />
    		<oauth2:refresh-token />
    		<oauth2:client-credentials />
    		<oauth2:password />
    	</oauth2:authorization-server>
    
    	<bean id="userApprovalHandler"
    		class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
    		<property name="tokenServices" ref="tokenServices" />
    	</bean>
    
    	<oauth2:client-details-service id="clientDetailsService">
    		<oauth2:client client-id="test-client" secret="123456"
    			authorized-grant-types="authorization_code" />
    	</oauth2:client-details-service>
    
    	<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="clientDetailsService" />
    	</bean>
    
    	<bean id="tokenStore"
    		class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore"></bean>
    And my access confirmation controller:
    Code:
    @Controller
    @SessionAttributes("authorizationRequest")
    public class ConfirmationController {
    
    	private ClientDetailsService clientDetailsService;
    
    	@RequestMapping("/oauth/confirm_access")
    	public ModelAndView getAccessConfirmation(Map<String, Object> model) throws Exception {
    		AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest");
    		ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());
    		model.put("auth_request", clientAuth);
    		model.put("client", client);
    		return new ModelAndView("access_confirmation", model);
    	}
    
    
    	@RequestMapping("/oauth/error")
    	public String handleError(Map<String,Object> model) throws Exception {
    		// We can add more stuff to the model here for JSP rendering.  If the client was a machine then
    		// the JSON will already have been rendered.
    		model.put("message", "There was a problem with the OAuth2 protocol");
    		return "oauth_error";
    	}
    
    	@Autowired
    	public void setClientDetailsService(ClientDetailsService clientDetailsService) {
    		this.clientDetailsService = clientDetailsService;
    	}
    }
    I also write a simple test client to test it. But I got a "java.lang.NullPointerException" in "ClientDetails client = clientDetailsService.loadClientByClientId(clientAu th.getClientId());" when I logged in the server and try to get user's authorization in the /oauth/confirm_access.

    After I searched solution for this, I add " create-session=“stateless” " in the XML configuration file, I can't even log in the server before entering the ConfirmationController.

    Any solution for this?

    Thank you very much in advance!

  2. #2
    Join Date
    Jun 2005
    Posts
    4,241

    Default

    How did you get to the /oauth/confirm_access page? If you didn't go through /oauth/authorize then there will be no AuthorizationRequest in the session.

  3. #3
    Join Date
    Mar 2013
    Posts
    3

    Default

    Thank you, you are right!

    I configured my client rest-template resource userAuthorizationUri with "/oauth/confirm_access" wrongly. By changing it to "/oauth/authorize", it works now.

    However, I got another error after access confirmation when the client tried to get access token from the server:
    Code:
    java.lang.IllegalStateException : An OAuth 2 access token must be obtained or an exception thrown.
           at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121)
           at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:216)
           at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:168)
           at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:89)
           at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:479)
           at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:123)
           at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:460)
    When I debugged this, I found the code of TokenEndpoint which mapped to "/oauth/token" is not even executed.

    Here is my client configuration:
    Code:
    	<http auto-config='true' xmlns="http://www.springframework.org/schema/security">
    		<custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="clientContext" />
    		<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    	</http>
    	
    	<authentication-manager
    		xmlns="http://www.springframework.org/schema/security">
    		<authentication-provider>
    			<user-service>
    				<user name="s" password="s" authorities="ROLE_USER" />
    			</user-service>
    		</authentication-provider>
    	</authentication-manager>
    	
    	<!--apply the oauth client context -->
    	<oauth2:client id="clientContext" />
    
    	<bean id="tokenServices"
    		class="org.springframework.security.oauth2.client.token.JdbcClientTokenServices">
    		<constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    	</bean>
    
    	<bean id="secureResource"
    		class="oauth.client.ExtendedBaseOAuth2ProtectedResourceDetails">
    		<property name="clientId" value="test-client" />
    		<property name="clientSecret" value="123456" />
    		<property name="accessTokenUri"
    			value="http://localhost:8080/spring-oauth-helloworld/oauth/token" />
    		<property name="userAuthorizationUri"
    			value="http://localhost:8080/spring-oauth-helloworld/oauth/authorize" />
    		<property name="clientAuthenticationScheme" value="form" />
    	</bean>
    
    	<bean id="secureResourceService" class="oauth.client.SecureResourceService">
    		<property name="secureResourceURL"
    			value="http://localhost:8080/spring-oauth-helloworld/security"></property>
    		<property name="secureResourceRestTemplate">
    			<oauth2:rest-template resource="secureResource"></oauth2:rest-template>
    		</property>
    		<property name="tokenServices" ref="tokenServices"></property>
    	</bean>
    
    	<!-- Jdbc DataSource -->
    	<bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    
    		<property name="driverClassName" value="org.postgresql.Driver" />
    		<property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
    		<property name="username" value="postgres" />
    		<property name="password" value="123456" />
    	</bean>
    How does this happen? I appreciate your help.

  4. #4
    Join Date
    Jun 2005
    Posts
    4,241

    Default

    I don't know what your ExtendedBaseOAuth2ProtectedResourceDetails does. If it doesn't have a grant type of "authorization_code" then your client is not authorized to use it.

  5. #5
    Join Date
    Mar 2013
    Posts
    3

    Default

    I made ExtendedBaseOAuth2ProtectedResourceDetails extend AuthorizationCodeResourceDetails and override isClientOnly() method, makes it return true so I don't need to login in the client side.
    Code:
    import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
    
    public class ExtendedBaseOAuth2ProtectedResourceDetails extends AuthorizationCodeResourceDetails{
    @Override
    public boolean isClientOnly() {
    	return true;
    }
    }
    I also tested it with Facebook's OAuth server, it works well and I get my Facebook profile as expected. So I suppose there is something wrong in my server side.

  6. #6
    Join Date
    Jun 2005
    Posts
    4,241

    Default

    Quote Originally Posted by readjay View Post
    I made ExtendedBaseOAuth2ProtectedResourceDetails extend AuthorizationCodeResourceDetails and override isClientOnly() method, makes it return true so I don't need to login in the client side.
    I'm not sure that makes a lot of sense since AuthorizationCodeResourceDetails is clearly not a client only protocol. If you have something that works, then don't let me stop you, but it seems like you might want to try and understand why it works and fix it another way.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •