In my application, I need to use Feign client with Oauth2 token. However, hystrix executes feign operation in another thread and due to SecurityContextHolder is threadLocal my application could not get the required value. Therefore, after some research I found that "hystrix.shareSecurityContext" config param provides to share this threadlocal objects in hystrix threads. And it worked.
However, is it secure to use this config param? Is there any possibility that threadLocal objects end up in another wrong thread under high traffic? How can i verify that threadLocal objecst are shared within only correct hystrix threads? Because not related hystrix threads should not get these tokens because of this config param.
Thanks in advance.
Related
I am using Zuul edge server to proxy requests to a bunch of session scoped controllers and stateless REST end points. Has anyone figured out a way to add the JSESSIONID in the subsequent request while proxying requests to session scoped controllers?
The issue I am facing is that Zuul does not manage the JSESSION id and cookies in general this causes the Session scoped controllers to create a new instance for every request.
As far as I know cookies are by default blocked. But you can change it in configuration.
I think more information you can find in following documentation parts:
Cookies and Sensitive Headers
Ignored Headers
I have two spring-boot processes. I have Spring Security enabled on both, and I'm using Spring Security OAuth2 SSO setup. I'm also using Eureka and Zuul to allows calls into Boot1 to call into services in Boot2. UI is using Angular with REST calls into the services, and the token being used is a Json Web Token.
This all seems to work, certainly in the UI. All the requests use the Authorization header (which contains the JWT) and the spring security filter in the services successfully parse the JWT and extracts the Security Context from it. As part of the Spring Web processing, it adds a JSESSIONID value to the client's cookie.
Recently, I only had Spring security on Boot1. When calling rest services into Boot1, which end up using Zuul to forward requests to Boot2, all I required in the rest client was to include the Authorization header with the JWT and it all worked fine.
However, I have recently added Spring Security to Boot2 (using the #EnableResourceServer annotation) and now rest calls fail unless I have both the Authorization header as well as a Cookie header that contains a JSESSIONID value. Calls don't fail, but they return empty values.
I've enabled logging to Spring Security, and it validates all correctly in Boot1. It's going into the same ZuulFilter. But there's no activity on Boot2.
Is there something in Zuul that requires a JSESSIONID value to be defined in order for it forward the request? Or is this in Boot2, where it is expecting a JSESSIONID header value due to the introduction of Spring Security filters?
--- update ---
I've stepped through boot1. From what I can see, code in the OAuth2TokenRelayFilter is throwing an exception. Specifically, the method getAccessToken is calling restTemplate.getAccessToken().getValue (line 90, version 1.1.0-RELEASE) which throws a UserRedirectRequiredException.
So, while the TokenRelayFilter has a token, it's attempting to refresh it. When it receives an exception, it's throwing a BadCredentialsException instead of using what's already been defined.
--- update 2 ---
Putting a breakpoint in OAuth2RestOperationsConfiguration, making rest calls without the JSESSIONID always ends up with a new DefaultOAuth2ClientContext to be created, as it's trying to create session-scoped beans. With the JSESSIONID, it's using a persisted DefaultOAuth2ClientContext, which will have the context.
So, is it possible to, when constructing the DefaultOAuth2ClientContext, to see if the request contains the token and uses it? Or something like this? We're trying to move to stateless services, and this seems to be a hurdle towards this.
This turned out to be an issue with the client-id values used by the different parts of the system.
Looking at OAuth2TokenRelayFilter, it is attempting to refresh the token if the client-id defined for the resource server (boot1) matches that which is defined as part of the token contained within the token provided with the request. In my case, this was true: the token was defined using the same client-id.
That really is not correct. When I update my rest client to use a token, but using a different client-id when requesting the token, then the request is forwarded correctly as expected, without the need for a jsessionid. This is exactly what I want.
I suspect that this was caused, in the end, by incorrect use of client-id values by the components of my system.
OAuth's access token/refresh token flow seems wildly UN-thread-safe to me. Help me understand it better.
Let's say I'm integrating with an API that leverages OAuth (like this one). I have my access token and I'm making API calls -- all is well in the world. But then my access token expires, and I need a new one. No problem, I use the refresh token that I was issued, and I get a new one.
Everything above sounds fine and dandy... But not in a multi-threaded world. Meaning, if the above actions all occur twice at the exact same instance on separate threads (e.g., two users request an API call simultaneously against the same object), and there can only ever be ONE access token alive at any given time, then won't one cancel out the other? And in a highly-transactional app wouldn't this happen a lot.
I have a strong feeling that this is a dumb question, but I can't wrap my brain around how this can be thread-safe.
Oauth is a protocol. It depends on a particular implementation whether or not that implementation is "thread safe".
Oauth2 != Oauth: How is OAuth 2 different from OAuth 1?
And REST APIs (like the one you cited) are inherently stateless, so there's really no question of "thread safety".
Finally, here's a good discussion on how to share an OAuth2 credential (that is, once you've established the credential) between multithreaded applications:
Optimizing OAuth 2.0 Requests
In multithreaded applications, the credential should be shared between
threads. Refreshing of the credential should be performed
synchronously to avoid a race condition.
The client libraries make sharing a credential across threads
straightforward. Each client library has a session (or user) object
which is constructed with a credential that it reuses throughout its
lifetime. To share the credential across threads, simply construct
each session using the same credential. In all client libraries, the
credential is a thread-safe object and refreshes itself synchronously
when its access token expires.
For example, in the Java client library, you would create a Credential
as a singleton and share it across all sessions.
I have some issues with oauth grant_type password flow.
When my app make a request to a protected resource it, using a ExchangeFilterFunction in a spring WebClient, make a request to obtain a access_token. If access_token is expired the app make a new request.
The problem is: in my implementation, if a thread detect a expired access_token it make a request to obtain a new token, in the meantime, other threads will do the same and N threads may at the same be trying to get a new access_token.
The fastest and most primitive way to solve this problem is blocking (e.g. syncrhonized keyword in java) the code snippet that gets a new token from the other threads, in this way only one request is made, but this will block all threads. When the first thread receives the new token, the other threads will be released, but now they will no longer need to make the request because they will detect a valid token.
As stated earlier, this is an implementation-specific tweak. I don't know if spring-security takes that care, but as far as I know, there's nothing in the oauth protocol specifying how to handle this.
Im trying to undertand how to properly identify which provider a returning authorization request was initiated by. I see three approaches:
Use provider specific redirect_uri callback URIs. /oauth2/<provider-name>/callback etc.
Encode provider id/name in state parameter somehow
Store a pending provider id/name in the web session
Try to verify response with all used providers
I've read parts of the OAuth2 spec but I can't find anything discussing it. Looking at other client implementations it seems as provider specific URIs is the most common solution. Am I missing something?
Clients may not be multi-tenant and are tightly integrated with a single Authorization Server, so there's no need to store a provider identifier because there's only a single fixed one. That may be the reason why there's no obvious solution.
Multi-provider clients like your's should store the provider identifier as part of the state. This is because the state should be protected, and the provider specific redirect_uri is not. One could play an access token for provider A against the callback for provider B and thus defeat the purpose of a provider specific callback.
state can be protected either by reference to server state or to an encrypted cookie, or by value in the form of a self-contained encrypted structured value for the state parameter, and thus can be a safe mechanism to store the provide identifier.
I'm using System.Net.Http.HttpClient to talk to a RESTful service in an MVC4 application on the back end. Depending on the user making the request the authentication header will be different for communication with the RESTful service, so the values to set in the header should be cached for each user. These values may change during a session's lifetime.
I am using StructureMap for DI. Some questions:
According to this it sounds like there should be a single instance of HttpClient for all requests. Although some say directly injecting the HttpClient may be a bad idea due to it being IDisposabe, others say that it's not necessary to dispose it. So, what is the best way to inject HttpClient?
Is it possible that the single instance of HttpClient can become disposed of or invalidated during run time (maybe the REST server reboots)? If so, then I think there is no choice in directly injecting HttpClient and it must be wrapped in a manager class that will check if the HttClient instance is valid and instantiate a new client if there's a problem. The issue is that I don't see a way make that test.
Where is the best place to cache the user specific authentication header information? I don't think that passing the information to the service layer from the controller is clean, as it seems to be suggested here, so I'm thinking an HttpSession scoped injected object in the data layer is the way to go here, but would love to hear other ideas.
Create the HttpClient when your MVC4 application starts and dispose it when it shuts down. If the server you are calling with the HttpClient reboots that will not require you to create a new instance of HttpClient. TCP connections are managed independently under the covers by the ServicePointManager.
I don't understand your question regarding user specific auth information. Are you trying to get your MVC site to impersonate the user when you call to the RESTful service? If so, then just set the Auth header on each request.