shiro validation issue in filter class - java

I am facing issue with shiro.
We have two applications(two WARS) on the same weblogic server 12c.
One WAR is UI which was integrated with CAS.
Second WAR is Jersey Rest services.
My problem is UI was auntheticated succefully and JsessionID was passed back to Rest Services while communicating with them.
Before reaching to the service we wrote one shiro filter class each time Subject is valid or not.
And also in our UI there is a requirement to call the Rest Service (One specific service) in every one minute.
Issue: Each time call reaches to shiro filter class, we are getting the different subject. i tried to print the sessionId from subject (each time its different), even though user was authenticated successfully in UI and in the backend some time user name is shown as null. Can you pls help.
Subject subject = getSubject(request, response);

There are a few things that typically cause this.
If you are handing the login yourself (by calling something like subject.login() directly, instead of letting the ShiroFilter handle it)
Both application servers are managing the sessions outside of Shiro: See https://shiro.apache.org/session-management.html#session-storage
That said, I'd need more details of how your app is setup. What do your cookies look like, how are your app servers configured, etc.

Related

JAVA - Cross application authentication

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

How can i transfer session data of a logged in user to another Java application

I have a legacy application. The login system is very simple like it takes username/password from user and runs a database query and validate the user.Now, i have created a link inside that legacy java application, that lands to a completely separate Java application dashboard page (written in Spring MVC).As of now, the new spring application as completely separate application and no user validation is implemented there. I want something like if somebody click the link(he can only access the link after logging in to the legacy application), it redirects to the new application along with user session data. So that user also sees himself logged in to the new application. And if he log out from the new application, I want him to be logged out from the legacy application too.
Legacy application- Simple servlet jsp based java application, runs on tomcat 5.5
New Application - Written in Spring MVC 4 and runs on tomcat 6
Both the tomcat containers reside on the same red hat box.
Any help will be highly appreciated. Thank you
You could try to develop a AuthenticationSuccessHandler for the legacy application and have it set the Autentication from SecurityContext in a shared memory between the two application on success. On logout, destroy the object.
For the new application, develop a filter or a handler that for a request checks to see if there is an Authorization in the shared memory associated with the SESSIONID from the request. If it's no longer there, force spring to destroy this session, logging you out.
AuthenticationSuccessHandler: http://docs.spring.io/autorepo/docs/spring-security/3.1.7.RELEASE/apidocs/org/springframework/security/web/authentication/AuthenticationSuccessHandler.html
SecurityContent: http://docs.spring.io/autorepo/docs/spring-security/3.2.2.RELEASE/apidocs/org/springframework/security/core/context/SecurityContext.html
shared memory: http://hazelcast.com/
Of course, this is only a fragile link between the two applications and maybe you should think about redeveloping the legacy application in a way that it best serves it's purpose of a CAS, such as exposing a webservice for login, and have a login handler for the new application call the webservice for an attempted login and decide using the answer whether to login the user or not. This way, you only have one session (on the new application) and you can scale easier the legacy app (if needed and not blocked by other restraints).
This is only an oppinion and without a more detailed look at your application, it might prove useful or total rubbish :)
Let's say your are connected on server A. On server B, you have your Spring MVC app.
You should develop on server B a webservice that create a Secure Token, encrypt it with a symectric algo. Send the token to the server A.
Server A then calls an other webservice on server B that use the token to authenticate.
When you will use the token to login server A can decrypt it to verify that it's the one issued previously.
You can find various documentations and examples on the web for token based authentication.

How to force authentication challenging for every request in REST?

My understanding is that a RESTful service should be totally stateless. Every time I invoke the service, I must pass all the information it needs to operate properly.
However, when it comes to authentication I get rather confused about how this should work, particularly in terms of session management.
I am using basic authentication and the first time I make a request, the client gets challenged (or I can pass the authentication information in the header from the beginning). But once the user has been authenticated, the server will not challenge this client anymore as long as the session is alive.
This means that I need to provide some mechanism for the current user to logout (terminate his/her session).
It would look like the right way of doing this would be to change my configuration somehow so that every request is challenged for authentication, but I have no clue how this plays with session management.
Am I supposed to invalidate the session manually after every request?
Or is there way to force the clients to be challenged every time a request is made?
You can find lots of questions out there about security with REST, and even books about how to implement different models of authentication. But I have not found a good answer on how to deal with session management, logging in and out. So either I am doing something wrong or I am misunderstanding something important here.
I would appreciate any thoughts or guidance on how this should be properly handled.
I am using Jersey 2.4 with Tomcat 7.
If you're authenticating with HTTP Basic, the client is challenged the first time only because the Authorization header isn't being sent from the client. Once it's sent and the server sends something other than a 401, the client caches those credentials and re-sends them with every request.
You shouldn't create sessions in a stateless app, not only because they aren't used, but because they require overhead to manage (even empty ones). The servlet architecture, however, cannot prevent code from creating sessions, such as when the code calls either httpServletRequest.getSession() or httpServletRequest.getSession(true). So you need to ensure that you don't use any code (or frameworks) that do this.
Interestingly enough, Tomcat will still generate a JSESSIONID cookie for the client to use, and under most configurations of the container, you can't turn this off. However, if sessions aren't created, the cookie is essentially ignored (and a new JSESSIONID cookie will be generated on every request).
And, because the app is stateless, there is no concept of login or logout. All authentication is done per request.
Note that, depending on your particular app, pragmatism may trump pure RESTfulness. There are cases where "a little bit" of server state is really the only way to provide some types of security to the app (such as cross-site request forgery, anything with nonces, etc.)
If you are doing a RESTful webservice you shouldn't handle sessions.
The first time you connect to the API you need to pass the authentication check in order to obtain an authentication key.
This key is how your API will identify its users.
You shouldn't invalidate the session and you shouldn't force your users to re-authenticate.

How to attach to an existing Java EE session

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.

Passing on LPTA token on webservices call isn't working

I've got a j2ee web application using j2ee security, so the identity of the user is propagated from WebSEAL to the application, running in WAS7. I'm now trying to make a SOAP webservices call and propogate the user identity in that webservices call. To do this, I grab the LTPA (WSCredential) and LPTA2 (SingleSignOnToken) using the WSSubject calls and attach them to the webservices call using.
bp.getRequestContext().put(Constants.REQUEST_TRANSPORT_PROPERTIES,sendTransportHeaders);
where bp is my BindingProvider. This all should work. But when I make a webservices call, I get back this exception.
Cause =java.io.IOException: Unable to deserialize the Subjects in this Context
I looked at the fields within the LTPA token and all seems right (same realm between the token and the j2ee security realm webservice I'm calling, the token is forwardable, etc), and I cannot find much about this error online, except for (what seems to be an unrelated) case when trying to pass it into the EJB and one case where the realms don't match.
Any ideas? Thanks.
Can you state clearly as to what you are trying to do here?
You should be able to pass the LTPA tokens across transparently with just configuration instead of trying to write some code to achieve the same.
The Web Applications making the Web Service calls to another WebSphere server.
have a quick read at this.
http://www.ibm.com/developerworks/websphere/techjournal/0607_desprets/0607_desprets.html
Things in WAS7 should be very similar to WAS V6.
HTH
Manglu
#jeffsix: are you trying to make a webservice call from application running in one websphere server to another application in another websphere server? Make sure LTPA keys are same on both server.

Categories