PDA

View Full Version : error: No OAuth 2 security context has been established



ildella
Nov 12th, 2010, 09:45 AM
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.consumer.OAuth 2RestTemplate">

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)

stoicflame
Nov 13th, 2010, 08:32 AM
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?

ildella
Nov 14th, 2010, 05:24 AM
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.DelegatingFilterPro xy</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.ContextLoaderListe ner</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.

stoicflame
Nov 16th, 2010, 05:40 PM
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...

ildella
Nov 17th, 2010, 02:19 AM
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?

stoicflame
Nov 17th, 2010, 10:55 AM
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.

bjornharvold
Jul 4th, 2011, 10:16 AM
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.

karpaczio
Dec 6th, 2011, 03:22 AM
Maybe you are handling AccessTokenRequiredException before it reaches OAuth2ClientContextFilter.

swang30
Dec 6th, 2011, 02:35 PM
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>

Dave Syer
Dec 7th, 2011, 02:26 AM
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.

karpaczio
Dec 7th, 2011, 02:48 AM
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.

Dave Syer
Dec 8th, 2011, 02:27 AM
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.