Zuul and JSESSIONID - netflix-zuul

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

Related

ASPNET MVC 5: Anti-forgery cookie not present

I've got an app that uses antiforgerytoken to secure all forms. the app is hosted on a web site that has the http binding set to the 8080 abd the https set to the 443 (default https port). Until now, I made sure that all the requests were made through https (The MVC app was using the required https filter, web config had the cookies entry requiressl set to true and owin had the auth cookies also set to https).
Recently, we had to change things because now we've got a firewall which handles the https requests for us. it will always serve the response through https to the final client, but I had change my app so that it could be called through http.
I've removed the required https filter, the required ssl for the cookies from the config and changed the owin auth cookies settings, and thought everything would be ok. Unfortunately, that didn't happen and I've started getting the anti forgery token cookie missing exception during validation. Now, the thing is that everything works out if I use https, but it will break if i change to http (which is in port 8080).
I've ended up changing the anti forgery configuration settings from within the global asax, but I'm not able to find a good explanation for the previous problem. in other words, why does the https access work without any problems but the http access ends up throwing an exception saying it can't find the anti forgery cookie...
any ideas?
Thanks,
Luís
More likely than not, you're using secure cookies (cookies sent with the Secure tag). These will only ever survive on HTTPS connections. As soon as SSL is dropped, so are any secure cookies. You could turn it off, but that actually opens up an attack vector on your users, allowing their cookies to be exposed in plain text through protocol-switching.
The best thing you could do is keep it secure all the way. Just because SSL is being provided by the firewall, doesn't mean you can't implement SSL on your site as well. The only difference is that you would need a self-signed cert, since obviously the external domain will not apply. Other than that there should be no problem proxying to a secure site internally, rather than an unsecure one.

HeaderHttpSessionStrategy x-auth-token is it safe?

Is it safe to use HeaderHttpSessionStrategy? one can get hold of the x-auth-token and the same session can be simulated across browsers and machines
Note that cookies themselves are in fact HTTP headers. The header named Cookie contains your cookie, which makes your concern applicable to both session strategies Spring Session provides out of the box (although cookies can be considered safer since they are domain restricted).
Ultimately, what will make both strategies safe is the use of SSL transport, i.e. HTTPS.

Rest call requires JSESSIONID (Spring boot, Spring Security, OAuth2, Zuul)

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.

Setting a cookie on all subdomains in Rails 4 and Ember

We have a Rails application that is the API component running on api.domain.com and a front-end application in Ember.js running on www.domain.com.
When Ember.js sends a POST request to a route in the API, /events, we want the API to set a cookie to remember a unique user identifier.
Hence this method in the Events controller:
def set_tracking_cookie
cookies[:our_company_distinct] = {
value: create_identifier,
expires: 1.year.from_now,
domain: :all
}
end
As you see, the cookie is set on the entire domain, and is set to expire in a year.
The point is that the next time Ember queries the API, it will be able to read this cookie. However, this is not the case.
Each time the front-end queries the API, the API is unable to find the cookie, nor does it show in the cookies in my developer tools.
The Ember requests set the Access-Control-Allow-Credentials header to true, and I can confirm that the cookie is indeed sent in the response from the API with the correct values for domain, name, path, expiry, etc.
Am I missing something?
Thanks!
For anyone else going through a problem sending/receiving cookies in this way, here are some things I found helpful when I was debugging and ultimately fixed the problem:
When you use the Chrome's (or any other browser's) devtools, examine each request and check it to see if the cookie is being sent from the API on the request where you expect it to be sent, and if all subsequent requests from Ember (or whatever other JS framework for that matter) send this request. In Chrome, go to "Network > [request] > Cookies". Ensure that the front end is sending the cookie properly and that it indeed receives it properly.
We found that this was the best way of adding support for the CORS cookies to Ember was to be done like so: http://discuss.emberjs.com/t/ember-data-and-cors/3690

.NET MVC HttpClient lifecycle

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.

Resources