I have different java web applications running on tomcat as different modules and one java web application as an addon running on the same tomcat server as another different module. I want to use the addon within the different applications (which essentially appears as a popup and is just one javascript file with a few URL-mapped controllers at the back end). I have allowed cross domain requests for the addon within the Tomcat realm, so the applications can access the popup and retriece the data.
Eg. in WebApp1, [http://localhost:8080/page1.html]:
ajaxGet(http://localhost:8081/getPopup, function(html){
showPopup(html);
});
The architecture of all applications is a simple JSON based request-response driven UI with javascript at the front end and URL-controller/servlet mappings on the JAVA-backend.
It works fine, but of course, it will also work for any requests from within the applications in the realm even if they are not authenticated. ie, even from the login page, I can request the popup.
How shall I take care of the authentication? Considering the addon doesnt need to be connected to the database for separate authentication, its authentication depends on whether the calling application is already authenticated or not.
Thanks in advance for your inputs. :)
Actually you need authorization, which usually depends on authentication. Authentication is the process of telling the service who is making the request, while authorization is the process of deciding if the principal is allowed to make the request.
The first thing you should do anyhow is adding authentication and authorization to the service which makes the popup content (/getPopup). Once you have secured that service, you actually have a number of choices:
implementing some single-sign-on framework
employing a federated authentication technology
forwarding requests from the calling application with a custom authentication scheme
...
Obviously, the simplest solution would be shipping everything together in a single deployment unit.
As a side note, mind the cookie session name when testing on localhost: cookies are bound to the hostname, not hostname + port, so the JSESSIONID issued by one service at localhost:X will be overwritten by the JSESSION id of localhost:Y
Related
I have been trying to read through existing information about this topic. I even installed KeyCloak server locally, configured the realm, the client and used Postman to send some requests to KeyCloak, and received some json response.
My problem is that - unless I misunderstand something - none of the descriptions seem to fit my goals.
Our application already has user management and we rely on user identity and roles / access rights configured in the system. The backend runs inside Tomcat and we run a Polymer 1.0 / Javascript frontend to call the REST services of our backend. I cannot get rid of user management as our DB is highly dependant on user to object assignment when deciding the scope of the objects for which the particular user is responsible.
All we need is an extension of our system by the possibility of foreign authentications (like social logins) in the future.
We have now explicit login that delivers a session cookie, Servlet filters to check the presence of this cookie, etc. In the server we use the login token / user identity in each REST call to filter the results from the DB to those available to the particular user.
What I need is a flow like:
in the fronted we check if we have active session (existing code)
if not we redirected the user so far to our own login page, logged in, created the session cookie on server and then returned it. On client side we saved this and added to every REST request as authoriation token.
Now with OIDC I'd like to insert a new unprotected query that checks if OIDC is configured. If not, we keep the old solution. If yes, I'd like to get redirected to KeyCloak login, and - and this is the most important for me - I'd like to get back the user identity (or some role that we associate administratively to the user - using which I could identify one of our configured users.
I tried experimenting with the Tomcat solution but that simply blindly hides the authentication procedure and merely allows or blocks REST access to the backend resources. This is not enough for me, I need some kind of user identity which I can use in the server side.
Also a javascript solution only provides communication between frontend and keycloak, but we need the backend to know who has logged in.
I think this topic and all the used lingo is too complicated for me. Could anyone give me some easy advice how to solve this with best practices?
Thank you very much
What is the correct way for a java heavy client to authenticate with an OpenAM protected servlet?
Java openAM sdk exists, which I have used and it does provide access to the SSO Token. Where things break down is when this same heavy Java client attempts to send serialized objects to a protected tomcat 7 (tomee+) servlet using this SSO Token id as a cookie. The OpenAM filter uses redirection with an embedded / hidden form containing credentials. This breaks the serialized object communications.
So what is the right way to have a Java heavy client authenticate such that it can then send serialized objects back and forth to a protected servlet? Is this even possible?
There are several ways to authenticate a client:
use the REST API to authenticate the client (/identity/authenticate or /json/authenticate)
using the ClientSDK AuthContext API
sending POST requests to /UI/Login (not necessarily the best way..)
After acquiring the token the only thing you have to make sure of is that you send the session cookie to the protected pages. In case you receive a self-submitting form for JAAS, then that means that you are using the agent in J2EE_POLICY or ALL mode and Java EE declarative security is enabled. Possible solutions for this problem area:
modify the client so it copes with the JAAS FORM login content (i.e. grab the input values and perform a POST manually), after this possibly you will also have to send the JSESSIONID with all your requests.
consider removing protection for your servlets in web.xml, that way the container will not attempt to display the JAAS login form, but then this will also mean that you won't have the fancy JAAS integration either (isUserInRole/getRemoteUser/#RolesAllowed/etc)
move your servlet to a separate application, which can be protected in a different agent filter mode (URL_POLICY/SSO_ONLY), it would be still protected, but again without the JAAS integration..
Basically I can't think of an easy way of leveraging JAAS integration with the use of a heavy client without dealing with form based login.. At one point in time I was able to implement a Java EE application client that authenticated into the container's (agent's) realm using programmatic login and that worked, but I don't suppose your heavy client is actually a Java EE application client..
I have an external SOAP web service that attaches to our services layer inside the application. For the Web 2.0 application, the services layer uses the session to store the user's "key chain" or the things a user can do in the system.
Now I'm trying to figure out how to do the same thing with my web service client to our services layer. The problem is that the web service URL can't contain a cookie that holds the session ID. (If I'm wrong, please say how and I'll do it that way.)
When the web service client connects the first time, I require a login and generate a security key that uniquely identifies that user and will expire within a certain period requiring them to login again.
I'd like to find a way in my endpoints to re-attach to the proper session for that security key and then the security will work automatically.
My endpoints are currently being served from tomcat.
How can I get there from here?
All input appreciated.
I ended up using REST to come back into our webapp through the URL so that I have a session. I connected to it that way.
We have the need in a project to implement single sign-on for two different web applications, one being our own and one is implemented by someone else. For our own application we have user/password stored (encrypted) in the database. Since our application will be integrated in their environment, we now need a mechanism to let us authorize the user already being logged in at their side without showing a login screen again.
Since I'm not a security expert myself, I started reading (on a high-level) about a few techniques regarding SSO, e.g. OpenID, Kerberos, SAML, CAS - but I have not yet gained practical experience.
Before marching in the wrong direction - can someone provide me with own experience in that field and point me to a framework to use or a good (and recent) article about how this should be done?
One more infomation: The customer talks about preferring to pass encrypted tokens between the two webapps. Does this make sense? And does this lead to a certain technique?
We use a SAML realization for this purpose ( https://svn.softwareborsen.dk/oiosaml.java/sp/trunk/docs/index.html ) - it was easily integrated inside our existing web applications.
The working scheme can look like as follows: you will have a login page, where the SAML framework redirects user. so, after successful login, he got a cookie with the auth token, and redirected back to the web application page. you will also have an identification webservice, which you can call, passing the token provided, and be able to get the auth credentials (user role, etc) from there, so all your web applications can identify this user as logged in.
I have an application with login Id and password. From this application, onclick of a certain menu item, I want to redirect to a different application which also has login Id and password.
I am trying to do this with session.setattribute but going nowhere.
Both the applications are built on Java EE using Struts and Hibernate. Can someone suggest how to do it?
What you are looking for here is what's called "Single Sign On", that is different applications sharing a users credentials between them so the user only has to log in once.
As you have already discovered, sessions are not shared between web applications. Indeed, there are no provisions in the Java Servlet specification for this. Depending on what application server you are using and your deployment architectyure, there are a number of proprietary solutions for this purpose. Simplest example is of you are using tomcat and all your applications are deployed to the same virtual host and realm (and using the same domain). Then you can use the single sign-on valve.
As, your applications are deployed on the same domain, you can add a cookie with authentication token in the response and read the value of authentication token in the request in the other application.
Other option I can think of is, Create a Authenticated value and put it in database, and send the redirect request to other application with this value as a request parameter. Your other application can read that auth value and validate with database and let the user pass login and password page.
You cannot communicate directly through the HttpSession between 2 separate applications. What you need to do is use cookies in order to achieve this communication.
Also take a look at this thread, as yours seems to be a possible duplicate of that one.