java.lang.IllegalStateException: No OAuth security context has been established. Unable to access resource 'goodAuthenticationId'.

Spring JIRA | Nick Williams | 4 years ago
  1. 0

    I'm using 2-legged OAuth to connect to a RESTful web service. I do not use or need authentication tokens. I have a simple public/private key shared secret and authenticate using that. Here is my simple code example: {code:lang=Java}RSAKeySecret signatureSecret = new RSAKeySecret(privateKey, publicKey); final BaseProtectedResourceDetails protectedResourceDetails = new BaseProtectedResourceDetails(); protectedResourceDetails.setConsumerKey("myConsumerKey"); protectedResourceDetails.setSharedSecret(signatureSecret); protectedResourceDetails.setSignatureMethod(RSA_SHA1SignatureMethod.SIGNATURE_NAME); protectedResourceDetails.setUse10a(true); protectedResourceDetails.setId("/check"); CoreOAuthConsumerSupport consumerSupport = new CoreOAuthConsumerSupport(); consumerSupport.setStreamHandlerFactory(new DefaultOAuthURLStreamHandlerFactory()); consumerSupport.setProtectedResourceDetailsService(new ProtectedResourceDetailsService() { @Override public ProtectedResourceDetails loadProtectedResourceDetailsById(String s) { return protectedResourceDetails; } }); OAuthRestTemplate restTemplate = new OAuthRestTemplate(protectedResourceDetails); restTemplate.setSupport(consumerSupport); Set<HttpMethod> methods = restTemplate.optionsForAllow("http://nwilliams:8080/app/services/Rest/check");{code} However, I was getting this exception: Exception in thread "main" java.lang.IllegalStateException: No OAuth security context has been established. Unable to access resource 'goodAuthenticationId'. at org.springframework.security.oauth.consumer.client.OAuthClientHttpRequestFactory.createRequest(OAuthClientHttpRequestFactory.java:45) at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:84) at com.puresafety.oauth.test.ContentTypeHeaderInterceptor.intercept(ContentTypeHeaderInterceptor.java:40) at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81) at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:67) at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46) at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:49) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:446) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409) at org.springframework.web.client.RestTemplate.optionsForAllow(RestTemplate.java:365) The solution turned out to be to change the last line of my code to: {code:lang=Java}Map<String, OAuthConsumerToken> tokens = new Hashtable<>(); tokens.put("/check", new OAuthConsumerToken()); OAuthSecurityContextImpl securityContext = new OAuthSecurityContextImpl(); securityContext.setAccessTokens(tokens); OAuthSecurityContextHolder.setContext(securityContext); Set<HttpMethod> methods = restTemplate.optionsForAllow("http://nwilliams:8080/app/services/Rest/check"); OAuthSecurityContextHolder.setContext(null);{code} But I was curious why this was necessary, so I took a look at the code (OAuthClientHttpRequestFactory#createRequest(...)): {code:lang=Java} OAuthSecurityContext context = OAuthSecurityContextHolder.getContext(); if (context == null) { throw new IllegalStateException("No OAuth security context has been established. Unable to access resource '" + this.resource.getId() + "'."); } Map<String, OAuthConsumerToken> accessTokens = context.getAccessTokens(); OAuthConsumerToken accessToken = accessTokens == null ? null : accessTokens.get(this.resource.getId()); if (accessToken == null) { throw new AccessTokenRequiredException("No OAuth security context has been established. Unable to access resource '" + this.resource.getId() + "'.", resource); }{code} And then I followed the access token to where it was being used (CoreOAuthConsumerSupport#loadOAuthParameters()): {code:lang=Java} String tokenSecret = requestToken == null ? null : requestToken.getSecret(); String nonce = getNonceFactory().generateNonce(); oauthParams.put(OAuthConsumerParameter.oauth_consumer_key.toString(), Collections.singleton((CharSequence) details.getConsumerKey())); if ((requestToken != null) && (requestToken.getValue() != null)) { oauthParams.put(OAuthConsumerParameter.oauth_token.toString(), Collections.singleton((CharSequence) requestToken.getValue())); }{code} The code *allows* the token to be null (and even anticipates that scenario). And my code, since it contains a null token value, is no different logically than if I had no token or OAuth security context at all. In a 2-legged OAuth scenario, it's completely valid for there to be no token (because you don't need one). It seems to me that the setting of an OAuth security context serves no actual purpose other than to bypass an error message that doesn't actually apply to my scenario. This code should be able to work without an OAuth security context and without an OAuthConsumerToken with a null, unused value.

    Spring JIRA | 4 years ago | Nick Williams
    java.lang.IllegalStateException: No OAuth security context has been established. Unable to access resource 'goodAuthenticationId'.
  2. 0

    I'm using 2-legged OAuth to connect to a RESTful web service. I do not use or need authentication tokens. I have a simple public/private key shared secret and authenticate using that. Here is my simple code example: {code:lang=Java}RSAKeySecret signatureSecret = new RSAKeySecret(privateKey, publicKey); final BaseProtectedResourceDetails protectedResourceDetails = new BaseProtectedResourceDetails(); protectedResourceDetails.setConsumerKey("myConsumerKey"); protectedResourceDetails.setSharedSecret(signatureSecret); protectedResourceDetails.setSignatureMethod(RSA_SHA1SignatureMethod.SIGNATURE_NAME); protectedResourceDetails.setUse10a(true); protectedResourceDetails.setId("/check"); CoreOAuthConsumerSupport consumerSupport = new CoreOAuthConsumerSupport(); consumerSupport.setStreamHandlerFactory(new DefaultOAuthURLStreamHandlerFactory()); consumerSupport.setProtectedResourceDetailsService(new ProtectedResourceDetailsService() { @Override public ProtectedResourceDetails loadProtectedResourceDetailsById(String s) { return protectedResourceDetails; } }); OAuthRestTemplate restTemplate = new OAuthRestTemplate(protectedResourceDetails); restTemplate.setSupport(consumerSupport); Set<HttpMethod> methods = restTemplate.optionsForAllow("http://nwilliams:8080/app/services/Rest/check");{code} However, I was getting this exception: Exception in thread "main" java.lang.IllegalStateException: No OAuth security context has been established. Unable to access resource 'goodAuthenticationId'. at org.springframework.security.oauth.consumer.client.OAuthClientHttpRequestFactory.createRequest(OAuthClientHttpRequestFactory.java:45) at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:84) at com.puresafety.oauth.test.ContentTypeHeaderInterceptor.intercept(ContentTypeHeaderInterceptor.java:40) at org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81) at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:67) at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46) at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:49) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:446) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409) at org.springframework.web.client.RestTemplate.optionsForAllow(RestTemplate.java:365) The solution turned out to be to change the last line of my code to: {code:lang=Java}Map<String, OAuthConsumerToken> tokens = new Hashtable<>(); tokens.put("/check", new OAuthConsumerToken()); OAuthSecurityContextImpl securityContext = new OAuthSecurityContextImpl(); securityContext.setAccessTokens(tokens); OAuthSecurityContextHolder.setContext(securityContext); Set<HttpMethod> methods = restTemplate.optionsForAllow("http://nwilliams:8080/app/services/Rest/check"); OAuthSecurityContextHolder.setContext(null);{code} But I was curious why this was necessary, so I took a look at the code (OAuthClientHttpRequestFactory#createRequest(...)): {code:lang=Java} OAuthSecurityContext context = OAuthSecurityContextHolder.getContext(); if (context == null) { throw new IllegalStateException("No OAuth security context has been established. Unable to access resource '" + this.resource.getId() + "'."); } Map<String, OAuthConsumerToken> accessTokens = context.getAccessTokens(); OAuthConsumerToken accessToken = accessTokens == null ? null : accessTokens.get(this.resource.getId()); if (accessToken == null) { throw new AccessTokenRequiredException("No OAuth security context has been established. Unable to access resource '" + this.resource.getId() + "'.", resource); }{code} And then I followed the access token to where it was being used (CoreOAuthConsumerSupport#loadOAuthParameters()): {code:lang=Java} String tokenSecret = requestToken == null ? null : requestToken.getSecret(); String nonce = getNonceFactory().generateNonce(); oauthParams.put(OAuthConsumerParameter.oauth_consumer_key.toString(), Collections.singleton((CharSequence) details.getConsumerKey())); if ((requestToken != null) && (requestToken.getValue() != null)) { oauthParams.put(OAuthConsumerParameter.oauth_token.toString(), Collections.singleton((CharSequence) requestToken.getValue())); }{code} The code *allows* the token to be null (and even anticipates that scenario). And my code, since it contains a null token value, is no different logically than if I had no token or OAuth security context at all. In a 2-legged OAuth scenario, it's completely valid for there to be no token (because you don't need one). It seems to me that the setting of an OAuth security context serves no actual purpose other than to bypass an error message that doesn't actually apply to my scenario. This code should be able to work without an OAuth security context and without an OAuthConsumerToken with a null, unused value.

    Spring JIRA | 4 years ago | Nick Williams
    java.lang.IllegalStateException: No OAuth security context has been established. Unable to access resource 'goodAuthenticationId'.
  3. 0

    Can a custom spring-security AuthenticationProvider set up an OAuth2 Security Context?

    Stack Overflow | 5 years ago | phtrivier
    java.lang.IllegalStateException: No OAuth 2 security context has been established. Unable to access resource 'avop-services'.
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    JBoss Community / Mailing Lists

    sourceforge.net | 12 months ago
    java.lang.IllegalStateException: isCallerInRole() called with no security context. Check that a security-domain has been set for the application.
  6. 0

    [EJBTHREE-404] Statefull beans looses security context after activation from passivated state - JBoss Issue Tracker

    jboss.org | 11 months ago
    java.lang.IllegalStateException: isCallerInRole() called with no security context. Check that a security-domain has been set for the application.

    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. java.lang.IllegalStateException

      No OAuth security context has been established. Unable to access resource 'goodAuthenticationId'.

      at org.springframework.security.oauth.consumer.client.OAuthClientHttpRequestFactory.createRequest()
    2. org.springframework.security
      OAuthClientHttpRequestFactory.createRequest
      1. org.springframework.security.oauth.consumer.client.OAuthClientHttpRequestFactory.createRequest(OAuthClientHttpRequestFactory.java:45)
      1 frame
    3. Spring
      InterceptingClientHttpRequest$RequestExecution.execute
      1. org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:84)
      1 frame
    4. com.puresafety.oauth
      ContentTypeHeaderInterceptor.intercept
      1. com.puresafety.oauth.test.ContentTypeHeaderInterceptor.intercept(ContentTypeHeaderInterceptor.java:40)
      1 frame
    5. Spring
      RestTemplate.optionsForAllow
      1. org.springframework.http.client.InterceptingClientHttpRequest$RequestExecution.execute(InterceptingClientHttpRequest.java:81)
      2. org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:67)
      3. org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
      4. org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:49)
      5. org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:446)
      6. org.springframework.web.client.RestTemplate.execute(RestTemplate.java:409)
      7. org.springframework.web.client.RestTemplate.optionsForAllow(RestTemplate.java:365)
      7 frames