Announcement Announcement Module
Collapse
No announcement yet.
error: No OAuth 2 security context has been established Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • error: No OAuth 2 security context has been established

    Hi.

    I am trying to replicate the tonr2 facebook example on a clean app without using spring mvc.

    I copied the xml config from tonr2, from applicationContext.xml I got <http> <authentication-manager> and the <oauth:resource> for facebook.
    From spring-servlet.xml just keep the restTemplate bean:

    <bean class="org.springframework.security.oauth2.consume r.OAuth2RestTemplate">

    that I injected in one of my services. The startup works but when I call, from a test environment as well from a "mvn jetty:run" environment, the line

    restTemplate.getForObject("https://graph.facebook.com/me/friends", ObjectNode.class);

    I get:

    java.lang.IllegalStateException: No OAuth 2 security context has been established. Unable to access resource 'facebook'.
    at org.springframework.security.oauth2.consumer.OAuth 2ClientHttpRequestFactory.createRequest(OAuth2Clie ntHttpRequestFactory.java:38)
    at


    Now, who is supposed to inject the context in the OAuth2SecurityContextHolder? I can't understand why in the torn2 app that context is not null.

    Thanks for help.


    The complete exception

    java.lang.IllegalStateException: No OAuth 2 security context has been established. Unable to access resource 'facebook'.
    at org.springframework.security.oauth2.consumer.OAuth 2ClientHttpRequestFactory.createRequest(OAuth2Clie ntHttpRequestFactory.java:38)
    at org.springframework.http.client.support.HttpAccess or.createRequest(HttpAccessor.java:76)
    at org.springframework.web.client.RestTemplate.doExec ute(RestTemplate.java:434)
    at org.springframework.web.client.RestTemplate.execut e(RestTemplate.java:401)
    at org.springframework.web.client.RestTemplate.getFor Object(RestTemplate.java:199)
    at com.shoppers.web.AuthTest.testname(AuthTest.java:2 0)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.junit.runners.model.FrameworkMethod$1.runRefle ctiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallabl e.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExpl osively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod .evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements .RunBeforeTestMethodCallbacks.evaluate(RunBeforeTe stMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements .RunAfterTestMethodCallbacks.evaluate(RunAfterTest MethodCallbacks.java:82)
    at org.springframework.test.context.junit4.statements .SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.runChild(SpringJUnit4ClassRunner.jav a:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild( BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner. java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRu nner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentR unner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRu nner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRu nner.java:184)
    at org.springframework.test.context.junit4.statements .RunBeforeTestClassCallbacks.evaluate(RunBeforeTes tClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements .RunAfterTestClassCallbacks.evaluate(RunAfterTestC lassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.ja va:236)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.run(SpringJUnit4ClassRunner.java:180 )
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestR eference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecutio n.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:197)

  • #2
    The context is set up by the spring security filter. Do you have your web.xml set up so the request is passed through spring security?

    Comment


    • #3
      Originally posted by stoicflame View Post
      The context is set up by the spring security filter. Do you have your web.xml set up so the request is passed through spring security?
      Yes:

      <filter>
      <filter-name>springSecurityFilterChain</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFil terProxy</filter-class>
      </filter>

      and the mapping as well and the context loader at the very end of web.xml

      <listener>
      <listener-class>org.springframework.web.context.ContextLoade rListener</listener-class>
      </listener>


      But same results as in the test environment where, indeed, no one loads web.xml, it's just

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration({ "classpath*:web-application.xml" })

      How can I simulate the SpringSecurityFilter to set up the context in the test environment without having to run and embedded servlet container? I can't find any doc about.

      Comment


      • #4
        I'm afraid I'm coming up short here. I think that I'm safe in making the assertion that if the request passes though the org.springframework.security.oauth2.consumer.OAuth 2ClientContextFilter, you won't be getting the "No OAuth 2 security context has been established" message. It's probably a configuration issue, but I don't have enough visibility into your project to determine what could be happening.

        And unfortunately I don't know much about how to set up the test environment for this case...

        Comment


        • #5
          Originally posted by stoicflame View Post
          I'm afraid I'm coming up short here. I think that I'm safe in making the assertion that if the request passes though the org.springframework.security.oauth2.consumer.OAuth 2ClientContextFilter, you won't be getting the "No OAuth 2 security context has been established" message.
          Wait, this is interesting, I never mentioned OAuth2ClientContextFilter, here or anywhere in my code.

          How is that filter supposed to be invoked?

          Comment


          • #6
            You usually don't have to set it up by hand into the spring security context. It's expected that you just use the oauth namespace configuration, specifically the <oauth:client> configuration element, which will attach the OAuth2ClientContextFilter to spring security.

            Comment


            • #7
              Has this been resolved? I am having the same issue with converting tonr2 to be my own oauth client. I am starting up Tomcat for testing and have already successfully logged into the client side. But when I call anything that requires external data through oauth, I get the same error as listed above.

              Comment


              • #8
                Maybe you are handling AccessTokenRequiredException before it reaches OAuth2ClientContextFilter.

                Comment


                • #9
                  Hmm, oauth2:client is supposed to set the filter automagically? It's never worked for me unless I injected the sec:http element with a custom filter declaration, like so:

                  <oauth2:client id="oauth2AuthenticationClientFilter"> blah blah blah... </oauth2:client>
                  <sec:http>
                  <sec:custom-filter after="EXCEPTION_TRANSLATION_FILTER"
                  ref="oauth2AuthenticationClientFilter" />
                  blah blah blah...
                  </sec:http>

                  Comment


                  • #10
                    That is correct (but it used to be that <oauth2:client/> tried to inject the filter automagically). See the samples for a template. I believe the docs also explicitly mention the custom filter.

                    Comment


                    • #11
                      What I wanted to say in previous post, is that even if your application has properly defined filter, it may still now work. If you have SimpleMappingExceptionResolver configured (without any mappedHandlers and mappedHandlerClasses),
                      then it will not rethrow AccessTokenRequiredException
                      then filter will not catch this exception and retrieve access token.

                      Comment


                      • #12
                        Correct. If Spring Security cannot catch its own AuthenticationException and AccessDeniedException a lot of features don't work as expected. It's a common mistake in general with Spring Security and not really an OAuth specific concern, I think.

                        Comment

                        Working...
                        X