Remember-Me with Spring Security, various questions - session

I'm using Spring Framework 3.0.5 and Spring Security 3.0.5 for developing a webapplication where users can log in and log out, using Remember-Me-Service, if they want to.
As I don't have pretty much experience, I wonder if it's working correctly. I use PersistentTokenApproach (with my own implementation, because I use Hibernate.) I can see the cookie is created on login and deleted on logout.
If I have an valid Remember-Me-Cookie and close the Browser, Im successfully logged in again when I open the browser again. So far, so good.
Now, I'd just like to know if those things I noticed are working as they are expected to or if I maybe did make a mistake.
1) When a user logs in without remember-me and the browser-tab is closed (not the browser itself), on reopening a new browser-tab he is still authenticated (he's using the same JSESSIONID). When closing the browser and reopening again, he isn't authenticated anymore. Regarding the security of a webapplication, is this a recommended ("normal") behaviour?
2) When remember-me used and the user is successfully authenticated (by login or later by cookie), there are no more checks on the cookie. that means, if meanwhile the user is online I'd delete the cookie from the database, the user would still be logged in, allowed to watch even the secured pages. I guess this happens because he was authenticated before and keeps using the same SESSIONID. When I close the browser and reopen it again, he isn't authenticated anymore.
3) When I dont own a cookie and open the main page, for every request I send (every picture, every file on the page) the server is checking for the rememberme-cookie. Is that correct?
Sorry for the newbie-questions, but I just want to make sure everything is working as it should. :-) Thanks in advance!

1) As far as tabs within a browser go, I am pretty sure they all share the same browser session. If you try using gmail or other web-based services you'll see the same behaviour when you close / open tabs. With older versions of IE (maybe version 6) separate instances had their own sessions, unless they were spawned from existing IE instances.
2) This sounds correct. Its not really ideal to hit the database on every request after they have been authenticated.
3) That is correct, as by default the spring security filters will be filtering on /* - and trying to look for authentication info. You can add excludes to your security config for resources you dont need to protect- ie
<http> <intercept-url pattern="/images/**" filters="none"/>

Related

Remember me for WebFlux Security application with SESSION and X-CSRF token

I have a NextJS app that communicates with a Spring backend, I'm getting the SESSION and X-CSRF cookie correctly but they only last for the browser session, when the browser window is closed and then reopened I want my users to be able to still be in the session and not have to login again every time.
I know that Spring Security has "Remember me" unfortunately I'm using WebFlux Security and ServerHttpSecurity doesn't have the remember me functionality, I saw this issue https://github.com/spring-projects/spring-security/issues/5504 but couldn't understand well what they mean with the solution.
I'm using Spring Session and since we can't have remember me, I don't know what exactly are the best steps to take? Would I have to set the Max Age of both cookies and used them for the days that I want my users to be logged in? Is this the best course of action?
I don't want to migrate to regular Spring Servlet Security unless it was the only way to solve this.
Since RememberMe isn't on WebFlux Security applications therefore the only solution I think of, is with the cookies.
You could modify the session cookie in the webflux application by using this guide from Spring Session, for the CSRF token, you could set the max age on CookieServerCsrfTokenRepository, like it was implemented here and that change is coming in the next Security versions.
By setting the max age, you can still use the same session when you reopen the browser window, unless the server session times out.
I don't know if that's the best solution, but if someone wants to add something else that would be great.

Spring Security "Remember Me" cookie gets deleted on browser closed event

I've followed Spring Security's instructions and managed to authenticate my users using JDBC in a Spring Boot project with "Remember Me" feature enabled (and setAlwaysRemember(true)). The "Remember Me" cookie gets created in the client's browser and the Token gets inserted into the "presistent_logins" table without fail.
But here comes the dilemma, When the client closes the browser, the "Remember Me" cookie gets removed automatically, which somehow makes all my effort effectless.
what would be the point of having Remember Me feature, if the cookie which is an essential requirement, gets removed on every browser closed event. Therefore, the user has to do the login all over again.
Here is a picture that shows the remember me cookie has been created after a successful login.
Do I have to take some special measures to make sure that the cookie gets preserved in the browser?
Chrome >>
Firefox >>
It's not the browser who is clearing the remember-me cookie. It's your spring app which tells the browser to clear that cookie (by giving an old expiry time).
So why does spring do that?
Because internally spring is throwing BadCredentialsException. You should debug RememberMeAuthenticationProvider class to make sure why it's throwing that exception.
In my case, the remember-me secret key was different than the one I used in my PersistentTokenBasedRememberMeServices class.
So please debug your application to find out the root cause of it...
Finally had to use normal mode of Remember Me feature (not DB persistence mode) in order to have this working. :(
When I use DB to persist session information, upon closing the browser, the "remember-me" session vanishes somehow!

Tomcat disable session not working

I have several apps deployed in Tomcat 7, and use Keycloak to manage user login and logout of these apps. Logout does not work i.e., does not log the user out and redirect to Keycloak's login page. Then I found the JSESSIONID cookie is still present, once I deleted the JSESSIONID cookie, the logout link works as expected. So I tried to disable Tomcat's session by putting
<%# page session="false" %>
in the header of my apps' JSP pages. Unfortunately, this still does not seem to disable Tomcat's session, I still see JSESSIONID cookie present. I am wondering if anyone has a solution to this problem? I believe the presence of the Tomcat session interferes with the Keycloak's SSO session, and causes Keycloak logout to not work. This has to be a common problem Keycloak users encounter, Tomcat is so widely used for web apps.
Would appreciate any tips on how we should handle this!
I don't have specific experience with Keycloak, however, there's a principle that applies to most if not all Single-Sign-On (or external authentication) solutions:
SSO identifies a user and removes the burden of knowing passwords from typical applications. When a user signs in, an application server is often detached from the actual SSO system, thus it will need to cache the user once they're identified, just as if the user identified itself with a classic login.
On the logout side, you can either log out of the application itself (tomcat in this case) or you can log out of the SSO system (which seems to be what you're doing here). With the later approach, you're running into the problem of "Single Sign Out": Logging out of the SSO system should invalidate all sessions that once were initiated with the associated login. As I know it, the SSO system needs to keep track of all of the systems that have signed on through it and trigger an explicit logout there.
I can't tell you how to implement this in Keycloak, but hope that the general principle helps guiding you towards the solution:
The use or non-use of a session on Tomcat's side has nothing to do with the problem: You might have applications that legitimately store information in a session in addition to the signed in user - those applications should continue to work even if you're not comparing passwords in tomcat itself.
Edit, after your comment:
If this one page doesn't trigger the use of a session, any other code (e.g. the code that processes your login) still might trigger a session and then later delegate to the page that doesn't want to use a session.
I'd expect that you'll have to disable sessions in Tomcat's configuration e.g. through providing a custom "Manager" implementation. It looks like the default ones do not expect you to completely ignore sessions. As I've outlined above, I'd also expect sessions to be required even if you're not logging in through Tomcat itself.
Another way to avoid sessions (this is the indicator why I don't expect "no session" config to work) is to avoid calling any method on request/response that would trigger the automatic creation of a session. And it seems that you have such a method somewhere in your app.
(someone correct me if I'm wrong. This is mostly my educated expectation as I've never looked at this requirement)

Securing Spring Boot Web App With Spring Security Doesn't Work

I've spent about a full day attempting to get a very basic Spring Boot app with Spring security up and running to no avail. I cannot find a single example of code that works when I run it.
This example is from spring.io. Here is what I'm seeing in that example:
I start at http://localhost:8080 and see the welcome screen.
I click a link to http://localhost:8080/hello, which redirects me to http://localhost:8080/login.
I enter "user" and "password" as specified in WebSecurityConfig.java, which redirects me back to the welcome screen. I was expecting to be redirected to http://localhost:8080/hello.
When I click the same link to http://localhost:8080/hello I get the login screen again.
I've tried debugging via #EnableWebSecurity(debug = true) but there are no errors.
The above experience is endemic of what I experience when I download every example. Admittedly I'm new to Spring, and presumably I'm making some kind of newbie configuration mistake. Any help would be greatly appreciated.
I downloaded the code and ran using maven and it works perfectly fine. After logging in, for all subsequent page loads of http://localhost:8080/hello loads the page and not the login page again unless of course I log out. The problem you have mentioned may be caused by ( with quite high probability since you have mentioned it's endemic) is that your browser may be having issue with transmitting the default JSESSIONID cookie (which is set on first page visit and updated ( as good security practise by Spring security) on first login. For subsequent visits same JSESSIONID is sent to the server and it is a key for the session object stored on server which contains the now authenticated/authorized user. If some how this cookie is not transmitted back to server ( one reason could be it's disabled in browser setting) then your application (protected by spring security) would not know that you are an already authenticated user and will show you the login page again. For e.g, for Chrome you can see the cookie settings at Settings --> Content Settings --> Cookies --> Allow sites to save and read cookie data (recommended). You can also view the cookie header getting passed on each page load post successful login by using Developer tool in respective browser.

Spring Boot - How to kill current Spring Security session?

Currently I know that my setup is working because I was able to login properly using the basic HTTP authentication.
I used these properties:
security.basic.enabled=true
security.user.name=user
security.user.password=1qaz2wsx
security.user.role=USER
However, I want to relogin again. I tried clearing cookies (I assumed it was saved there), I checked my local/session storage and cookies in Chrome dev tools but it was blank.
I tried accessing my site in incognito and it asks me to login (for the first time since I only logged in to Chrome non-incognito).
How do I "kill" my session in Spring Security?
If you use basic authentication, the browser stores the authentication until you close it (or exit the incognito mode, if you used it). There is no possibility to delete the session on server side, since the browser would just reauthenticate. If you want to be able to logout, use form login.

Resources