We have a need to make a call to a servlet from an external application which is making a post request.
The servlet looks at the request, performs some processing and sets a attribute on the request or session and redirects to a JSF page which needs to retrieve the attribute set on the request or the session and do additional stuff.
For both cases I have been unable to retrieve the attribute/parameter set on the session or request from the managed bean and upon further debugging, it revealed that the session ids were different in servlet and in the managed bean.
Since this is a request coming from an external application, there is no session in the servlet so doing request.getSession(true); which is creating a new session in the servlet.
I was under the understanding that since these were part of the same application and using the same context that they would have the same session. Is my understanding incorrect?
Is there a better solution to this issue? (I did consider creating a Filter but thought might have the same issue with the session)
Any help in understanding better or resolving this issue will be appreciated.
As to how sessions work, carefully read this: How do servlets work? Instantiation, sessions, shared variables and multithreading.
In fact, the external application should have sent the very same session cookie as the JSF application is using. An alternative would have been to provide a callback URL including the jsessionid path fragment, which is composed as follows:
String url = "http://example.com/context/servlet;jsessionid=" + session.getId();
Again another alternative would be to generate an unique ID (with java.util.UUID) referencing an entry in application scope or even the DB and set it as request parameter in the callback URL. You should only manually cleanup it when the session is destroyed. You can use a HTTP session listener for that.
Related
UPDATE: After doing analysis for my original problem which is listed in the second section i found the issue could be due to 304 response below is the detailed explanation.
I have developed a web application where users clicks on the link and its takes him to servlet where i set few session variables and then forward it to jsp. First time when i access the application things work fine after closing browser and then opening browser and accessing application i get null pointer exception in jsp because it is trying to access session data the reason it i am getting 304 response for the servlet , so this means that servlet is not invoked and my jsp are getting called ? since servlet is not called session values are not set .
Is my understanding correct?
I am observing this only in IE9
--------------------- My original question is below --------
We have integrated Siteminder in our application , I have observed that siteminder cookie SM session is created for different domain where as my application specific cookie is created for proper domain.
For every request i see new smsession value but my application cookie remains same , even though the cookie remains same the values which I set in session using servlet are not available in my jsp.
I have printed the jsession id, the jsession id is same for all request.
Below is the flow.
User hits a URL siteminder intercepts it and asks for credentials once user successfully logs in he is redirected to servlet where i set few values in Session then i dispatch the control to index.html which has two frames . I am loading two jsp for these frames and in these jsps i am trying to access the session values which i am unable to get .
I am observing this behaviour only in IE9 but IE8 behaves correctly,
First time access works fine second time does not in IE9
Can anybody let me know if change in smsesson incurs changes in httpsession for java app ? i don't think so as Jsession id remains the same.
What could be possible reason for this.
Have you checked if the jsps being called in the frames has the same session id as the one in the servlet?
To give you background on SMSESSION and JSESSION:-
The SMESSION id cookie keeps getting changed by the web agent periodically and is usually tagged to the base domain. Example - If the application is hosted at a.b.com - the JSession ID will typically be set to the domain a.b.com and the SMSESSION will be set to the b.com domain. This is the default Siteminder behaviour since it assumes that all applications in the b.com domain need the cookie for SSO. You can change this using the ACO for the agent by either setting the domain name explicitly or setting the scope of the domain that needs to be used.
Unless your application has logic which depends on the value of the SMSESSION id and modifies the java session, the JSessionID cookie is not impacted by the change in the value of SMSESSION
After doing analysis i found that it was 304 response for the servlet which was causing issue. When application was accessed first time there was no issue but next since when i try to run the application it would result into issue because browser would have cached responses , hence server would send 304 response because of this servlet would not be called and session would not be set .
I have a servlet ,it creates the session and I need to pass that session to another servlet,
Is that possible ?
Yes you can.
Sessions are not specific to a servlet it is managed by your servlet container. So even if you forward request from one servlet to another and use request.getSession()the session will persist, provided you dont call the invalidate() or session timeout didn't occurs and both the servlets belong to same web application.
To add on :
When the first request comes from a user he is assigned a session and all further request\response will have in same session unless the session expires either due to session timeout or invalidate() method was called. The container manages session with two methods:
URL Rewriting.
Cookies.
I am developing an application that will serve multiple customer-organizations, each of them should be given access based on a fixed url. Example: domain/myapp/CustomerOrg1
Previously I always registered a new WAComponent-subclass for each of these entry-points. That does work but there has to be a better solution, I would like a single component-class to find out which URL the request uses (to then respond with the customer-org's homepage)
I tried:
registering a WARequestHandler-subclass; and it allows me to find out the full path (incl. /CustomerOrg1) but I am outside of any session and don't know how to get into one.
registering a WAComponent-subclass as /myapp, and it works in that it also handles /myapp/CustomerOrg1 automatically, however when I try to find out the URL used (by self session url inspect) it claims to be only the base-url (/myapp).
Try
self requestContext request uri
and if you are not in a component but any object you can do
WACurrentRequestContext value request uri
Please be aware that the uri you get in the answer by Norbert is in a production environment a value that has already been processed, and possibly modified, by your (Apache/nginx/etc) webserver responsible for static content and load balancing.
I have an asp.net application that I'm attempting convert the front end to Angular. Getting header information is important to the view. I'm used to getting the header information like so in C#:
httpContext.Request.Headers["USERID"]
How can I do the same thing in an angular controller?
In asp.net each request runs in its own independent context and hence the header access as you have shown in your code make sense.
This does not hold good for angular or in fact any client side framework. You can always get the headers for any request or response made using angular $http but the question is which request? During the lifetime of the app you would make many such requests.
Let's say you want to get the current userid, you can create a service that returns the logged in user. There are two ways to implement such a sevice
create a method on server to return this data. Invoke this method from service and cache results
on the client side assuming there is a login request made through angular, implement a success callback method which can update the service with the logged user id.
You can look at $http documentation here to understand how to access headers.
Is there a way to get the server url (ex: http://www.myapp.com:8080/applicationFolder) without having access to a Request object ?
I need the url at aplication_start and in some classes where the Request object with all the goodies is not available.
note: I know that getting the application folder can be done using
VirtualPathUtility.ToAbsolute("~/");
HttpContext.Current.Request is a static property that always returns the Request object currently executing for the session.
I think all you need a custom solution to know when first request is made after application starts, and then you can send any email you want.. this is the similar problem with solution here http://weblogs.asp.net/reganschroder/archive/2008/07/25/iis7-integrated-mode-request-is-not-available-in-this-context-exception-in-application-start.aspx this do first initialization check in BeginRequest event.
There can be many different addresses all pointing to the same ASP.NET website, like using IP address or name. There might be more than 1 DNS name pointing to the same ASP.NET application. Therefore, HttpApplication, the parent class of Global, does not know which URL a visitor will use. Even IIS doesn't know. Therefore, you have to wait for the first request and then check in the request what URL the visitor uses to access your site. Something like this:
string baseUrl = Context.Request.Url.GetLeftPart(UriPartial.Authority);
One has to use Context to get access to the Request during Global.Application_Start, because Global.Request is not initialised yet.