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
Related
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.
I am trying to migrate an application A to a Weblogic 10.3.6 Application server running on Oracle Enterprise Linux Operating System. An application B is already residing in that weblogic server. Application A has a GUI with user login feature. However, application B does not. Currently application A and B are interfacing through an MQ.
My queries are:
1. Is it a feasible design to have both applications A & B ears in the same server?
2. If yes, how can they internally communicate?
3. Is there a security breach risk for application B due to user login feature of application A?
1) Yes, it is perfectly reasonable to run one or more Ear files on a server. There can be performance issues, and you may need to watch the JVM/Heap memory carefully (one app causing OutOfMemoryError will take down both).
2) Depends how you want them to communicate. The easiest way is probably to use remote lookup. WebLogic provides all lookups for application context etc in a JNDI tree. As long as the methods are exposed to allow remote calls (e.g. #Stateless #Remote annotations in JEE), you can call methods remotely. You can also use other methods such as MDB (message driven beans) if you don't want fast communication, or even Web Services (just bind to the same local server with a different Context root).
3) It depends how you login. If you use weblogic state to check if someone is logged in, then logging in to one application will log you into the other. You would need to look at WebLogic Roles and Policies. Basically set certain users into one Role for one application, and possibly have two different authentication mechanisms setup. Then use #RolesAllowed (or any other ways you fancy) to block access to classes/methods to only the given roles.
If you use your own log in method, I can't see an issue from the user side. Just be careful of what code gets used, and make sure you dont allow remote lookups you arent aware of (ie watch out for methods that could be subject to injection attacks, where malicious code could do a remote lookup to the other application). If you wanted you could still use WebLogic Roles and Policies to block this off anyway.
Is it possible to share Session state between web applications on separate servers? One of the web sites is using session state to maintain user credentials/info session state, the other is using forms authentication to maintain this information. Without modifications to the website using session storage, is it possible for the website using forms auth to read/access the session state on the other server? If not, which I assume is the answer, would it be possible if they ran on the same server? (i.e. the same app pool)?
Note: Both applications are under the same domain name (one of them will be a sub-domain)
As a note, the reason this is being asked is because a client is requesting a "single sign-on" approach between two websites. We're using forms authentication and the other site (which we cannot modify at this moment) is maintaining credentials/logon information in session
ASP.NET 4
IIS 7.5
Assuming the latter, you could try something like this:
first, make sure all the appliations are running in the same domain. If not, all bets are off. I don't know if there's a simple way to configure the domain property of the session cookie yet, so you may have to do it yourself, by setting the cookie domain property to the domain:
Response.Cookies["ASP.NET_SessionId"].Domain = ".mydomain.com";
you'll need to make sure that each application is configured to use either a common state server, or a db-backed session.
please follow the link : How to share session state across subdomains
If i had two different application running under the same solution but using different Databases can i share User credentials between those applications ?? any solution other Than The SSO and the Machine key in the web.config where the authentication is based on the default Asp.net Database ( i guess it's called the membership database )
if their is a solution could You please help
Are it two seperate IIS websites? And what are the real requirements you have? Just share some variables or move data from one application to another?
I'd think you'd probably better look into creating a service layer to receive and send information between sites. This way you can eventually seperate the two applications on different web front ends without problems.
This service layer can be implemented using different techniques like XML Web Services, WCF, or maybe you could look at the new ASP.NET Web API http://www.asp.net/web-api
edit:
Ok clear from the comments I got some more info:
Imho you could do two things: schedule a synchronisation using some mechanism (could be xml export / import) every day or so. But if you'd want realtime SSO, you could simply create a service on the webserver connected to the authentication database where the only functionality is to authenticate users. Something like a: bool validatecredentials(string username, string passwordHash). If you're not talking about thousands of authentication requests this will perform quite good using standard WCF or some other service technology. If you are talking about larger systems or implementations you should look at Claims based authentication, .NET has a technique called WIF to implement that. It works using a seperate STS (Security Token Service) to issue tokens with claims who a user is and what he is allowed to do, etc.
Is there an elegant solution for synchronizing sessions across multiple ASP.NET applications? I'm sure this could easily be considered a security hole, but there is a 3rd party ASP.NET application involved, for which there is no ability to extend. For this reason, a second [related] site is being developed, but will require direct access to the sessions created on the 3rd party application.
As an example, when a user logs in/out of one site, the same operation should occur on the other site. However, it's important to note that this goes beyond a typical SSO.
Using SQL Server to store is one of your most easy solutions.make sure you have proper permissions set on the SQL objects. I am not familiar with what Manu has suggested. There is actually one more way of doing it which is a little difficult. Its done by implementing a modification of the memento like pattern. App1 stores session info in the database but instead the other application App2 getting access to the DB, the session info is exposed via a service which App2 can reference. Once the user moves on to app2 and is authenticated, its session is restored using the service.
Hope that helps. It worked for me in one of my projects.
Try memcached session state provider: http://www.codeplex.com/memcachedproviders
Since the cache runs in a seperate service, I am pretty sure you can access the same storage pool from different apps.
Cookies are an option assuming the application is storing some key data in its cookies. If the other site is in the same domain, it can read them.
Use NCache - http://www.alachisoft.com/ncache/
It'll help you to acheive what you are looking for.
It has built in distributed ASP.NET session state cache as well, and will help you to share sessions across multiple sites. Details Here