Spring Boot with Embedded Tomcat: Session not persisting through restart - spring-mvc

The research I've done on this seems to indicate that this should happen automatically. Some writings suggest that it is required to place server.session.persistent=true inside src/main/resources/application.properties. I have done this and I believe sessions are still not persisting.
Some background: Using Spring Boot with embedded Tomcat and Spring MVC + Thymeleaf. The user "logs in" to my application using their google account. Once they are authenticated by Google, my application gives them a unique identifier which is stored as a property inside the user's HttpSession. This property is of type Integer. I do have an H2 database hooked up to this application but from what I've read I should be able to solve this problem without having to worry about storing sessions in the database.
When I launch the application using gradle (bootRun), I receive a cookie with my JSESSIONID as expected and I login with my user. The user can navigate to different pages in my Spring MVC application and they are still 'logged in' by virtue of the session attribute being set on the server side. When I stop the process in my IDE (to my knowledge this is not the same as terminating it) and restart it, then visit my application again in the web browser, I am immediately issued a different JSESSIONID.
It seems to me that the immediate problem is that my session is not being remembered between server restarts. I have seen some writings that hint at implementing my own 'session store' or something like that, but I assume that first it is necessary for the server to understand that this is the same session.
I'd be happy to provide more information that would help, thanks everyone who took the time to read this.
Final Notes:
I am not using Spring Session or Spring Security, at this point I don't anticipate needing to for this project.
This is a "prototype" application for my own personal use, so feel free to warn about design issues but it is not my intention to make it bulletproof from a security perspective.

Related

Impersonation using httpmodule, threading issue

We have as SAAS application that runs for multiple customers at the same time. All customers use the same application, and by checking the URL used to access the application, users are redirected to the correct data for the organization.
Underwater, every organization has their own database. To make sure that users don't accidentally end up in the wrong database, we want to impersonate the request being executed to a user that only has access to the correct database. We used to do this and this worked beautifully on IIS in classic mode.
However, in integrated pipeline mode, we run into a threading issue. We use an HTTP module to impersonate the request to the correct user in the "PreRequestHandlerExecute" event. The problem that (apparently) there is no guarantee that this method is executed in the same thread as the handler that actually processes the request. This causes the impersonation to sometimes not work because the thread processing the request is not impersonated.
I've created a test project in GitHub (https://github.com/PaulVrugt/ImpersonationExample/tree/master/ImpersonationTest) demonstrating the issue (apologies for the vb.net, but you'll get the idea). When you run the example connected to an IIS using integrated pipeline mode, you'll see that sometimes the impersonated user is not used, and each time it is not used, the managedthreadid of the thread processing the request is different from the thread used in the httpmodule.
Now that I understand why it "sometimes" doesn't work, I begin to suspect I'm going about this all wrong. Is there a way to achieve what I am trying to do?
We've already tried to impersonate in the prerequesthandler in the global.asax, but that results in the same issue.

Share SessionManager between two WAR's on same tomcat

Problem:
We have apache shiro authentication in our two applications, let's name them application1 (context is "/") and application2 (context is "/app2"). For basic authentication, it's working fine. We deploy these two applications on two tomcats (both applications on each tomcat) and then handle context sharing via tomcat 8 context sharing and for preserving sessions, we use memcached so that even if one tomcat is down, application and sessions remain preserved.
How session is already handled?
If user logs in on any of the two applications, their session is shared between two applications with getting the root context ("/") and then an interceptor to intercept any request and find if user is already logged in or not.
New Requirement:
Recently, we had to implement a functionality where we need to expire a certain user's all sessions on the basis of a certain trigger and I was reading about Apache Shiro's Session Management. I integrated in application1 and everything worked fine but now session sharing between application1 and application2 is gone.
I explained above scenario so that I could get right directions what exactly I should look for or try.
What I want to do is:
I want to somehow share shiro session manager between these two applications so that once it's shared, we can easily handle the session sharing part and rest of the functionality (invalidating sessions of some user) is already in place.
Question:
So, please tell me, if what I want to do is exactly what I should do and what I need to understand and read? OR if I am thinking in the wrong direction, please suggest me the right path.
I am the author of the book "Pairing Apache Shiro and Java EE 7" which you can grab for free here.
The Session clustering feature can be done using the CacheManager. Shiro is natively supporting EhCache & Hazelcast. I recommend you to use Hazelcast.
Here is a sample project on github: shiro-hazelcast-web-sample
To go deep in Hazelcast features, you can override Shiro's CacheManager, and implement what do you want of Hazelcast features:
Web Session Clustering
Generic Web Session Replication
Tomcat Web Session Replication

Authenticate users syncing time out for 2 different sites

I have been puzzling over this and can't think of an good way of doing this. I am developing a website that would require the user to log in to use the system. I'm thinking of using ASP.NET MVC 4's built in authentication. That isn't much of a problem.
The user would be able to use tools on another server (our server would authenticate him and tell the other website, he is good to go, these messages are passed via HTTPS using XML). The other server, require us to create an authentication token for the user to use when the messages are passed between us.
We need to keep the token in our database to authenticate for every request/response with the other server. Which means that this "token table" knows nothing about the forms authentication time out on our server and vice-verse.
Now the problem, let's say the user uses the other server's tools. He would be on the other server for a long time, this would cause the authentication on our server to log him out, since there doesn't seem to be any perceived activity. The other server will not log him out since we are manually maintaining the token. This would be a troublesome for the user, because now, if he needs to use our service, he'll have to log in again even though he was "online" all the time.
Is there a way to "sync" the 2 authentications? At first I was thinking of getting our server to look up the "token table" (instead of using the built in authentication) so that if the last activity was x ago, the user will be required to log in again, this would solve the untimely logging out from our server. But I'm worried about the security implications.
What would be the best way to do this?
Thank you.
Desmond
If I've understood you correctly you are using Forms Authentication in an MVC4 application to authenticate users, but users will also use another web service located on a different server and so while they are using this other server you don't want the MVC4 application's authentication (for the user) to timeout. Is that correct?
If so, one idea that comes to mind is that your MVC4 application could have an API to the external world that would take in a username and use RenewTicketIfOld() to refresh the timer associated with the ticket. You could do this via the other web server making an HTTP request or by simply placing some AJAX on the page to call the API on every page.
There are, of course, security concerns with this method that you would need to consider. Without knowing more about your situation I'm not sure what solution would be best.

Application uses anonymous authentication even though it is disabled in IIS

I have a diagnostic web application hosted in IIS7 that has Windows Authentication enabled and Anonymous auth disabled. This application generated some kind of a report where it includes information about what kind of authentication was used to view the site. Every time I browse to this site I get a message that I connected using Anonymous authentication which for me is unbelievable. The report works fine (tested on other machine) and the fact is that I do not get a credentials popup. How is this possible and how can I fix this?
First, i'm not knocking your diagnostic application, but it may be worth looking at the IIS logs (or indeed switching them on for your site) to see what IIS thinks is going on. If you're not familiar with IIS logs, I'd suggest writing them in Microsoft format (at least while you're sorting this problem). One of the key fields you get is the user id. If you really are hitting the pages anonymously, this id will be the id you configured to field anonymous requests. Otherwise, it will normally be the calling user's id (at least in a simple scenario).
Second, how many sites are you running? Are you sure you're going in through the expected site? Or maybe you're hitting the default site instead?
Third, bear in mind that authentication can be set at the site level but anso at the page level. Are you sure one isn't overriding the other?

Diving into ASP.NET Web API Authentication

I've been getting into the (relatively) new Web API that shipped with VS 2012 / MVC 4 / .NET 4.5, and have a custom message handler that handles authentication up and running. I also managed to hook it up to an old .NET 2.0 Membership Provider which was great.
I am now tackling the "authenticate with every HTTP request" issue by using a token in the HTTP request header, which I am comfortable with doing.
Now, for mobile apps when a user opens the app I show a login screen the first time, and don't show it again unless for any reason I get the "Unauthorized" message back. But for my web browser based projects I log in once and the browser (as long as it remains open) will remain authenticated.
What's the best way of forcing a time-out with this sort of authentication? I would prefer to log out based on inactivity, if anyone has done this. This one has me a bit stumped, so any guidance is appreciated :-)
Thanks!
There are two idle timeouts you need to consider.
Server Side idle timeout which expires to token you referred to
Client Side (mobile app) idle timeout which directs the user to re-enter credentials
For #1, You'd have to keep track of which tokens are active, or when they expire, etc... there are multiple ways to do this. How I'd recommend you implement it depends on if your deploying to IIS or Azure and if you'll be scaling out. In general though you want a central location where this information is stored. A DB works, but is relatively slow. Session State could work in Azure as the Session State can be shared across servers via App Fabric, but in IIS, you'd have to use an additinal component to share session state across the servers. Same holds true if you use the HttpRuntimeCache in .NET
It should also be noted that doing such checking server-side is critical so as to prevent someone from hijacking the token you refer to depending on how you ultimately decide to implement things.
For #2, What we did in our iOS app was keep track of the idle timeout. Each time user give input of any kind (e.g. BeginTouch event) in the app, we stop our idle timer and restart it. The timer is configure to take the user to the login screen should the timer fire. This same sort of thing should work well in Android, WP7, etc.

Resources