HttpSession Session ID different to FlexSession ID - apache-flex

I have a Flex application which is served via a JSP page. In this page I output the session ID using HttpSession when the page is loaded:
System.out.println("Session ID: " + session.getId());
In a very simple remote object hosted in BlazeDS (called from the flex application using an AMF Channel and standard RemoteObject functionality) I also output the session ID but this time using FlexSession (which as I understand is supposed to wrap around HttpSession).
System.out.println("FlexSession ID: " + FlexContext.getFlexSession().getId());
I would expect both IDs to be the same but this is not the case. The session IDs differ which is causing problems as there is data stored in the HttpSession which I need to be able to access from my remote objects within BlazeDS.
I've exhausted the reading material on BlazeDS and FlexClient/FlexSession/FlexContext but can't see why the FlexSession is not being linked to the HttpSession. Any pointers greatly appreciated.
I feel I must be missing something fundemental here, am I accessing the

I do not think that it is related to the FlashPlayer..is more related to the concept of FlexSession and how BlazeDS/LCDS works. For example you can have an active session even when not using the http channels - when using NIO/RTMP you are bypassing the application server and the http protocol. So it make sense to have an abstract class FlexSession with various implementations.
However when using BlazeDS FlexSession will wrap an HttpSession object internally, and removeAttribute/getAttribute/setAttribute are in fact calling the the same methods from the HttpSession object..so you can access all the data from the HttpSession. If not please provide more details.
However, it will not work when using RTMP channels(which exists only in LCDS by the way), you need to change your design in this case.

Thanks to both answers above I finally found the root cause and thought I'd share it on here.
The reason for differing session IDs was to do with the use of SSL for authentication and the use of AMF Channel rather than Secure AMF. Using the channel for the first time caused a new session to be created (hence the different ID) as the existing session related to the secure version of the site.
Silly configuration mistake but worth passing on - make sure that if using SSL that you're also using Secure AMF connecting to the secure endpoint rather than standard AMF or you'll run into the same session ID problems I faced.

Unfortunately this is just how the Flash player works. I have seen this same behavior many times.
The best solution I found was to establish the HTTP session and pass back the session ID. On the client side, you can then pass the session ID to the Flex application. You then send that ID from Flash to the server and use it to look up the existing session or establish a second session.
You will need to do something like this though, I have not been able to find a way to reliably get Flash to use the same session.

Related

Session state access in Web API across domains

I have a ASP.Net API implementation, where to store and access the data / variables across consecutive calls, I am using a session state object as shown below and it can be successfully accessed in the multiple calls to separate calls by a browser:
// Access the current session object
var blSession = HttpContext.Current.Session;
// create the BL object using the user id
BL accessBL = new BL(userID);
// Store the Bl object in the session object dictionary
blSession["UserBL"] = accessBL;
I have to enable the following setting in the Global.asax, for the Session object to be accessible:
protected void Application_PostAuthorizeRequest()
{
// Enable session state in the web api post authorization
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}
Issue comes in when the WebAPI shown above has to be accessed via another ASP.Net MVC client, which is separately hosted on a different machine, at that time same consecutive calls do not maintain the state as shown above and thus it leads to an exception, since the consecutive calls rely on session data to proceed.
I have seen a similar issue when I seen the similar issue when I use the Fiddler Debugger, as it gets hosted as a web proxy, so consecutive calls through that too fails, since it does not maintain the state. In my understanding, issue is due to setting the Cookie across domain, which doesn't seem to work across domains due to security reason
I know a workaround is to use an application wide variable like Cache, but please suggest if you have a way to get the SessionState work. Let me know if you need more details.
If you have not setup an alternative way to do SessionState, then the default behavior is to do it InMemory on the server. This is why you are seeing issues when the request is handled by a different ASP.NET server.
Web API calls are meant to be stateless. That is, they should not perform like a classic ASP.NET application that relies on the framework to store user specific information in Session variables across HTTP requests. For each call, pass in a user-specific identifier or token that you can then use to lookup information stored in your backend. You can store this information in your database or a distributed cache like MemCache for faster retrieval.

Use Spring Web Flow without state on the server

I'm reading the Spring Web Flow chapter in the book Pro Spring MVC. Unfortunately there's no explicit information, where the state during a flow execution is persisted. I assume it is saved in the JVM Heap and associated with the session.
Now HTTP is a stateless protocol (REST...) and I'd like to use Spring Web Flow without saving state on the server (besides the one and only state that a session might be authenticated).
One strategy is to send all parameters of the entire flow with every HTTP request of the flow (hidden input) and thus accumulating all necessary parameters until the flow has finished.
The overhead of re-validating parameters can be avoided with signatures over already validated parameters.
Do you know, whether it might be possible to use Spring Web Flow in this way? Has anybody already done this?
Update: Why?
Persisting state is not only a violation of the principles of HTTP as a stateless protocol but has practical problems too:
If the user browses with multiple browser tabs then this can lead to inconsistent state, race conditions or data loss.
Storing state on the server makes load balancing over several servers more complicate.
Testing and debugging becomes more complicate, because requests can not be tested or analyzed in isolation but only in the context of previous requests.
Cookies must be enabled to correlate servers sessions to requests.
The server needs to synchronize access to the server-side state.
The url of a request that also depends on server state does not contain all information necessary to bookmark the state inside a flow or to make sense of it in a bug report.
I've not yet looked at the details of Web Flow but I'm confident that one could have the same programming experience and still keep all information in the request parameters.
Update: I've now learned that my requested style of flow handling has a name: Continuations. The term continuation is more common in functional programming but it's apparently not uncommon to adapt the idea to HTTP interactions.
You might be interested in checking my bean flow FSM project (restflow):
https://github.com/alfonso-presa/restflow
Although it doesn't use Spring WebFlow, I think it may help answering the spirit of the question, as it allows the implementation of a stateless server orchestrated flow. I started this project because I wanted to make almost the same as you with spring WebFlow but I found it was not possible as state is stored in session (and also REST/json serialization is not built in).
It's main purpose is making an state-machine (just like WebFlow does) but with it's state stored in a bean, which you can persist in a distributed store, or easily sign or encrypt and send back to the client as continuation for next requests.
I hope you find it useful.
edit: I created a showcase project here: https://github.com/alfonso-presa/restflow-spring-web-sample

Why don't ASP.Net handlers support session by default

I understand that in order for a ASP.Net handler to support session state you need to implement both IHttpHandler and IRequireSessionState, but why isn't session state provided by default? If for performance reasons, then wouldn't it be better to have an interface like IDoesNotRequireSessionState?
Its because the session is block the asynchronous operations, and the handle is usually used for long time operations, like the making and download of a file - if you keep the session on long time operation you block the rest of your pages.
Also the handle is made with the idea of the minimum required to get a response.
About the session lock:
Web app blocked while processing another web app on sharing same session
jQuery Ajax calls to web service seem to be synchronous
ASP.NET Server does not process pages asynchronously
Replacing ASP.Net's session entirely
If for performance reasons, then wouldn't it be better to have an
interface like IDoesNotRequireSessionState?
Absolutely not, because then everybody implementing a handler must know about the existence of this interface. An HTTP handler is the fastest in terms of performance you might ever get from ASP.NET. So if you want to pollute it with crap like session then you'd better do it explicitly, and taking full responsibility of doing so, by implementing some interface that you should know about.

How to insert the username into MDC for the entire web request

I am trying to use a Mapped Diagnostic Context to add the username of the user making a page request to all relevant logging statements. However I have tried three different ways to make it work without success:
Pushing the username into the MDC after login and removing after logout. This method ends up mixing up which logging statement came from which user.
Using a ServletFilter to push the username into the MDC on each page load and pop it back off as the request ends. This only catches some of the data and only in Spring security layer.
Using a AOP #Around interceptor in front of all the Controller methods flat out didn't work.
Does anyone have any suggestions on how to make this happen?
What were the problems with MDC? What do you mean by Spring security layer? I used this approach in one web application and it worked well. Because MDC is bound to thread, all logging statements coming from this thread will have username set, i.e. service and repository layer as well.
Of course if some users are served from using threads (e.g. servlet 3.0 asynchronous processing, JMS listeners, executors), you will need the other way of injecting username to MDC in pooled threads.
Also see my answer here.

Can an HTTP connection be passed from IIS/ASP.NET to another application or service?

I'm looking into building an ASP.NET MVC application that exposes (other than the usual HTML pages) JSON and XML REST services, as well as Web Sockets.
In a perfect world, I would be able to use the same URLs for the Web Sockets interface as I do for the other services (and determine which data to return by what the user agent requests) but, knowing that IIS wasn't built for persistent connections, I need to know if there's a way that I can accept (and possibly even handshake) the Web Sockets connection and then pass the connection off to another service running on the server.
I do have a workaround in mind if this isn't possible that basically involves using ASP.NET to check for the Web Sockets connection upgrade headers, and responding with a HTTP/1.1 302 Found that points to a different host that has my Web Sockets service configured to directly listen to the appopriate endpoint(s).
If I completely understand your goal, I believe you can use the IIS7/7.5 Application Request Routing module to accomplish this.
Here's a quick reference: http://learn.iis.net/page.aspx/489/using-the-application-request-routing-module/
Rather than 302 responses you could use ISAPI_rewrite to direct to an appropriate endpoint (and manipulate the HTTP header to get it there)
http://www.isapirewrite.com/docs/
Otherwise no, IIS cannot natively pass off an HTTP connection. The current MSFT method is to use a 302 or something else that is intercepting the raw socket and performing header manipulation prior to sending to IIS (or whatever other application)
It strikes me that this would be a better question to ask Microsoft than to ask us. Web Sockets is new technology, and rather than looking for a hack, you might want to ask Microsoft how they plan to support it. IIS is their software. Poke around on http://iis.net (maybe in http://forums.iis.net) and see what you learn.
The way to do this is to use a unique Session ID that is associated with the Http Session. From the description, it seems like you might want to scope this to a single HttpApplication instance, but this is not necessary (you may also persist a session across many application instances). Anyway, this session ID needs to be attached somehow to each Http Request (either with a cookie, querystring, static variable with the HttpApplication instance, form data). Then you persist the identifying information about the Http session somewhere with the ID.
This identifying information may vary depending on your needs but could entail the entire http request or just some stripped down representation that serves your particular purpose.
Using this SessionID somewhere in the Http request allows you to restore whatever information you need to call and interact with the appropriate services. The instances of the services may also need to be scoped to the session as well.
Basically, what I am suggesting is that you NOT directly pass the Http connection to an external process, but instead pass the necessary data to the external process, and allow create a mechanism for sending callback data. I think looking into the mediator pattern may be helpful for you in understanding what I mean here. http://en.wikipedia.org/wiki/Mediator_pattern . I hope this helps.

Resources