Spring security, session concurrency control, expired-url cached in browser - spring

There's configuration for Spring concurrent session control:
<sec:session-management>
<sec:concurrency-control max-sessions="1" expired-url="/error/concurrency" session-registry-alias="sessionRegistry" />
</sec:session-management>
When I log into the application using two different browsers and then in first browser click some link requested url is redirected to the expired-url set into config. So far so good.
If I log in again into first browser and click link previously performed, expired url is retrieved from browser cache and error page displayed again instead original one. If I check disable cache in browser's developer tool original page finally appear.
There is no Cache-Control attribute into response header so the problem is how to set no-cache, no-store etc. in order to prevent browser caching when concurrency redirection occur.
I tried adding <sec:cache-control/> into <sec:headers> but without any success. I can see there is a Cache-Control header attribute for other spring security urls. Wondering why it doesn't exist in case of concurrency exceed exception.

Related

Why does JMeter HTTP Response differ from the browser response?

I have a magic link to access a website without logging in, let's say the magic link is something like this
https://key.example.exampl.tr/auth/realms/test/protocol/openid-connect/auth?client_id=my-react-client&state=ba453a80-d991-4b3b-a791-3fc2629aea03&redirect_uri=https://test.example.exampl.tr/&scope=openid&response_type=code&user_id=d0bcdd07-3198-4ab6-9cfd-d0b6341dbe00&key=7a1b4163-76e8-465c-a914-c68f16761698
when I use the link in the browser it works as expected and accesses the home page without asking me to log in. BUT when I use the same link inside HTTP GET Request using JMeter, it redirects me to the login page. Why is that happening and how to solve it?
This is happening as you browser stores specific cookies and caches for the particular request, whereas for jmeter you will request a new session every time, if you are not using HTTP Cookie Manager and HTTP Cache Manager explicitly.
Try clearing your browser history, cookies & caches and hit the same request/url, it would also redriect to the login page and behave same as jmeter does

SameSite cookies in JMeter

I'm developing a JMeter test for a site that requires "SameSite by default cookies" to be Disabled in Chrome, as shown here:
Turn off samesite enforcement in chrome version > 80
The site I'm testing just returns HTML pages; it does not have a separate API layer. The main element causing issues is a third-party component embedded in an iframe. The iframe content uses SSO to authenticate with the main site. In Chrome, if the SameSite setting is set to Default, I get a login page for the third-party component, rather than seeing the component render. If the SameSite setting is set to Disabled, then the third-party component renders correctly.
When I execute my test in JMeter, I'm encountering the same issue that I encounter in Chrome when "SameSite by default cookies" is set to Default--specifically, I get redirected to a login page.
However, when I execute the same sequence of HTTP requests in Postman, everything works fine.
Does JMeter have some SameSite cookie behavior built-in, and if so, how do I disable it?
UPDATE: following Dmitri's suggestion, I tried all the different cookie managers.
I also enabled cookie manager logging. If I set HTTP Cookie Manager's Cookie Policy to default, the "expires" attribute on the cookies causes an error:
2020-03-27 12:56:58,613 ERROR o.a.j.p.h.c.HC4CookieHandler: Unable to add the cookie
org.apache.http.cookie.MalformedCookieException: Invalid 'expires' attribute: Fri, 03 Apr 2020 17:56:54 GMT
at org.apache.http.impl.cookie.BasicExpiresHandler.parse(BasicExpiresHandler.java:64) ~[httpclient-4.5.10.jar:4.5.10]
at org.apache.http.impl.cookie.CookieSpecBase.parse(CookieSpecBase.java:113) ~[httpclient-4.5.10.jar:4.5.10]
at org.apache.http.impl.cookie.DefaultCookieSpec.parse(DefaultCookieSpec.java:140) ~[httpclient-4.5.10.jar:4.5.10]
at org.apache.jmeter.protocol.http.control.HC4CookieHandler.addCookieFromHeader(HC4CookieHandler.java:124) [ApacheJMeter_http.jar:5.2.1]
...
If I set the Cookie Policy to standard--"The RFC 6265 compliant policy (interoprability profile)" per HTTPClient docs--I don't see any cookie error messages in the log, but I'm still getting redirected to a login page.
If the application you're testing sends malformed cookies in Set-Cookie header JMeter might reject the cookies which don't match current domain of the HTTP Request sampler or expired or invalid by any other reason.
You can "tell" JMeter to be less restrictive by:
Choosing more "relaxed" cookie policy, i.e. netscape in the HTTP Cookie Manager
Add CookieManager.check.cookies=true line to user.properties file (JMeter restart will be required to pick the property up)
More information: HTTP Cookie Manager Advanced Usage - A Guide
If above steps don't help you can:
Increase JMeter logging verbosity for the HTTP Cookie Manager and friends by adding the next line to log4j2.xml file:
<Logger name="org.apache.jmeter.protocol.http.control" level="debug" />
and last but not the least, you can always extract cookies from the aforementioned Set-Cookie header using i.e. Regular Expression Extractor and manually add them the next request using HTTP Header Manager

Serve two pages from two server for one url

I would like to serve two different pages from two servers for one url. Something like facebook does with login page (login page vs profile page on same url).
How will server know what page to serve? I went with cookie because I couldn't think of other solution.
Also cookie removal is needed on logout. I ended up with branch on nginx configuration to push request to right server and removing(setting expired time) cookie there.
Ok and now the bug itself. Chrome caches this url and when user clicks on link(to the same url) chrome skips request to the server and open wrong version from cache. It works when "disable cache" in debug panel is checked and I also confirmed this by checking traffic with wireshark.
To recap urls from browser point of view:
ex.com/ - Server A
ex.com/login_check - Server A -> redirects to / with cookie
ex.com/ - Server B
ex.com/?logout - Server A and remove cookie
ex.com/ - chrome skips request and serves cached content from B
How can be this fixed? Moreover this approach looks like too much magic and many things can go wrong. Could it be done differently?
This can be fixed by adding header for response from both servers.
Cache-Control: private, max-age=0, must-revalidate, no-store;

too many sessions created by Spring MVC

I'm using Spring MVC, MySql and Tomcat 7.
Currently the application I'm developing can be accessed by 2 URLs namely IP:PORT/APP and www.app.com.
When accessing via www.app.com I see a session being created for every page/link that I open but it doesn't happen when I access via IP:PORT/APP.
I have a check for logged-in user in every page and due to too many sessions that check is failing and I'm being re-directed to my login page even after logging in.
Also when opening the www.app.com index page I see a jsessionid on the address bar and not when i open it via IP.
Any help/guidance is appreciated.
It seems that when you are accessing the page via domain name (www.app.com), cookie support is not found and hence the url rewriting is being done (i.e. appending jsessionid at the end of the url). But this is not observed while accessing the same page via IP Address (IP:PORT/APP), meaning cookie support is enabled at this time.
You can check if you have enabled some security settings that is not allowing cookies.
Further to this, it seems that even url rewriting is not helping as sessions are being created for every request.
You can use some HTTP Interceptors to analyze the request being sent and response being received in each case. You can use Developer Tool in Chrome to inspect this. Load you page in Google Chrome, Right Click on Page and Click 'Inspect Element'. Open the 'Network' tab. Reload the page. You can now inspect the HTTP Request Headers sent and Response Headers received for each request. Analyze the difference between the request using IP Address and requests using Domain Name.
Also, share the architecture of the application and the environment where you are testing the application.

No expires header sent, content cached, how long until browser makes conditional GET request?

Assume browser default settings, and content is sent without expires headers.
user visits website, browser caches images etc.
user does not close browser, or refresh page.
user continues to surf site normally.
assume the browse doesn't dump the cache for any reason.
The browser will cache images etc as the user surfs, but it's unclear when it will issue a conditional GET request to ask about content freshness (apart from refreshing the page). If this is a browser specific setting, where can I see it's value (for browsers like: safari, IE, FireFox, Chrome).
[edit: yes - I understand that you should always send expires headers. However, this research is aimed at understanding how the browser works with content w/o expires headers.]
From the the HTTP caching spec (section 13.4): Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entry, MAY return it without validation if it is fresh, and MAY return it after successful validation. This means that a user agent is free to do whatever it wants if no cache control header is sent. Most browsers use a combination of user settings and heuristics to determine whether (and how long) to cache in this situation.
HTTP/1.1 defines a selection of caching mechanisms; the expires header is merely one, there is also the cache-control header.
To directly answer your question: for a resource returned with no expires header, you must consider the returned cache-control directives.
HTTP/1.1 defines no caching behaviour for a resource served with no cache-related headers. If a resource is sent with no cache-control or expires headers you must assume the client will make a regular (non-conditional) request the next time the same resources is requested.
Any deviation from this behaviour qualifies the client as being not a fully conformant HTTP client, in which case the question becomes: what behaviour is to be expected from a non-conformant HTTP client? There is no way to answer that.
HTTP caching is complex, to fully understand what a conformant client should do in a given scenario, read and understand the HTTP caching spec.
Unless you send an expires header, most browsers will make a GET request for each subsequent refresh and will either get HTTP 200 OK (it will download the content again) or HTTP 304 Not Modified (and use the data in cache).

Resources