Announcement Announcement Module
Collapse
No announcement yet.
OAuth2. Authorization Code grant. Error when hitting AuthorizationEndpoint Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • OAuth2. Authorization Code grant. Error when hitting AuthorizationEndpoint

    I'm building OAuth2 authorization server using 1.0.1.RELEASE.
    My authorization server is configured like this:
    Code:
    	<oauth:authorization-server
    			client-details-service-ref="clientDetailsService"
    			token-services-ref="tokenServices">
    		<oauth:authorization-code/>
    	</oauth:authorization-server>
    When hitting '/oauth/authorize', I get following error:
    Code:
    2013-02-28 13:24:41.209:WARN::/oauth/authorize
    org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'authorizationRequest' cannot be found on object of type 'java.util.HashMap'
            at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:208)
            at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)
            at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:52)
            at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
            at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88)
            at org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint$SpelView$1.resolvePlaceholder(WhitelabelApprovalEndpoint.java:64)
            at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:146)
            at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:125)
            at org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint$SpelView.render(WhitelabelApprovalEndpoint.java:79)
            at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157)
            at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927)
            at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
            at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
            at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    I tracked the source of the issue to AuthorizationEndpoint.authorize method:
    Code:
    			model.put("authorizationRequest", outgoingRequest);
    After populating the model with 'authorizationRequest' parameter, the action redirects to
    Code:
    forward:/oauth/confirm_access
    The execution is passed to WhitelabelApprovalEndpoint.getAccessConfirmation method:
    Code:
    	@RequestMapping("/oauth/confirm_access")
    	public ModelAndView getAccessConfirmation(Map<String, Object> model) throws Exception {
    		return new ModelAndView(new SpelView(APPROVAL), model);
    	}
    From what I can see, the model here is expected to be containing 'authorizationRequest' parameter that was populated by AuthorizationEndpoint earlier. However, the model is empty, which eventually causes the exception above. When stopping on a breakpoint in this method, I can query 'authorizationRequest' parameter like this:
    Code:
    RequestContextHolder.currentRequestAttributes().getAttribute("authorizationRequest",0)
    From my understanding of Spring MVC, after forwarding from request A to request B a model populated in request A will not be passed to request B explicitly, but its attributes will be available via HttpServletRequest attributes. If so, getAccessConfirmation method may have a bug. Or (more likely) I'm just doing something wrong. If so, please suggest.

  • #2
    AuthorizationEndpoint has @SessionAttributes("authorizationRequest"), so that attribute should be in the session. Do you have a session?

    Comment


    • #3
      Originally posted by Dave Syer View Post
      AuthorizationEndpoint has @SessionAttributes("authorizationRequest"), so that attribute should be in the session. Do you have a session?
      Thanks for the answer. I don't have sessions disabled in <http session-create attribute in security XML configuration, so I suppose I have a session enabled. How can I check to tell for sure?

      Comment


      • #4
        You could trace the HTTP requests headers from your browser or other client. Make sure the cookie you get from the authentication step is the same as the one passed to the /confirm_access endpoint.

        Comment


        • #5
          Originally posted by Dave Syer View Post
          You could trace the HTTP requests headers from your browser or other client. Make sure the cookie you get from the authentication step is the same as the one passed to the /confirm_access endpoint.
          In both AuthorizationEndpoint and WhitelabelApprovalEndpoint the value of JSESSIONID cookie is the same (I have executed
          Code:
          ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getCookies()
          at runtime).
          This is the same cookies that was sent with the original '/oauth/authorize' request.

          In fact, I think that @SessionAttributes annotation is not valid when used on different controllers. From the documentation, "Annotation that indicates the session attributes that a specific handler uses", where I guess handler=controller. I have created a simple test case which mimics the same behavior that AuthenticationEndpoint and WhitelabelApprovalEndpoint expose:
          Code:
          @SessionAttributes({"hello"})
          @Controller
          public class StartController {
          	@RequestMapping("/start")
          	public ModelAndView end(){
          		HashMap<String, Object> model = new HashMap<String, Object>();
          		model.put("hello", "world");
          		return new ModelAndView("forward:/end", model);
          	}
          }
          @SessionAttributes({"hello"})
          @Controller
          public class EndController {
          	@RequestMapping("/end")
          	public ModelAndView end(Model model){
          		System.out.println("Got model: "+ model);                    //this is empty
          		return null;
          	}
          }
          In EndController, model is empty.
          If I declare both 'start' and 'end' actions in one controller, model is populated with 'hello' attribute, as expected:
          Code:
          @SessionAttributes({"hello"})
          @Controller
          public class StartController {
          	@RequestMapping("/start")
          	public ModelAndView end(){
          		HashMap<String, Object> model = new HashMap<String, Object>();
          		model.put("hello", "world");
          		return new ModelAndView("forward:/end", model);
          	}
          
          	@RequestMapping("/end")
          	public ModelAndView end(Model model){
          		System.out.println("Got model: "+ model);         //this contains 'hello=world'
          		return null;
          	}
          }
          Does AuthenticationEndpoint -> WhitelabelApprovalEndpoint chain work for you?
          Last edited by denis_k; Mar 1st, 2013, 08:06 AM. Reason: Examples were completely screwed up

          Comment


          • #6
            Neither of your samples should compile because you have a local variable with the same name as a method parameter. I'm not surprised the first one didn't work, even if you rename one of them. The second one should also not work as you described (for the same reason) even if you changed the name of the local variable (you are adding "hello" to a local map which goes immediately out of scope not the Spring MVC model).

            Originally posted by denis_k View Post
            Does AuthenticationEndpoint -> WhitelabelApprovalEndpoint chain work for you?
            I haven't tried it explicitly in a while, but the sparklr sample has exactly the same code (with a custom handler for /confirm_access) and it works.

            Comment


            • #7
              Ah, I was entering examples by hand and screwed them up completely. I'll edit. I'll also take a look at sparklr sample, thanks for suggesting it.

              Comment


              • #8
                OK, I figured it out. It was a bug in Spring 3.1.0.RELEASE. Starting from 3.1.2.RELEASE, @SessionAttributes are persisted among controller as expected. I don't know how this slipped from me initially when I was testing with fresher Spring versions.

                Comment

                Working...
                X