1

I'm using Azure ACS in my ASP.net MVC 3 website (hosted in Azure too), the scenario is this: A user first enters my website and fills a one field form, then they need to chose a provider and login, but first I want to store the field value so when they come back from login I'm able to create a profile with this value for the loged in user.

So I believe when they first enter the site and then leaves to login and enters the site again those are two different sessions am I right? and that's the reason the stored data using session state (through SQL Server) is not present when they come back after login am I right? if this is true what would be the best approach then? if not then I'm doing something wrong storing temp data right?

Thanks

UPDATE: I have discovered that HttpContext.Application state works keeping the data, still I'm not sure if it's a good idea to use it in a controller considering it's in Azure, will it work on production properly??

Keoz
  • 394
  • 2
  • 16
  • You shall **not** use Application state for storing user-centric data. Especially in Azure (but not only in Azure). Quote from: http://msdn.microsoft.com/en-us/library/ms178594.aspx: *"application state is a useful place to store small amounts of often-used data that **does not change from one user to another**."* – astaykov Nov 26 '11 at 22:12
  • Yeah I really don't want to use state, thanks :) although it's not user data just data that will be public – Keoz Nov 27 '11 at 00:52

2 Answers2

3

You can pass state around in the WS-Federation redirect sequence using the wctx URL parameter. In the action that handles the initial POST request, you should get hold of the form parameter you want to keep, then redirect to you identity provider selection page (this will have to be a custom page) with the form parameter appended to the URL. When the user selects an IP on your page, you can pass the parameter on again using the wctx parameter. The WS-Federation passive requestor profile says that this should be returned to you eventually when the IP redirects the user back to your site.

This has some details

http://msdn.microsoft.com/en-us/library/bb608217.aspx

Edit: To get the wctx parameter out of the request when the user finally comes back to your app. Put something like this in the action code:

var fam = FederatedAuthentication.WSFederationAuthenticationModule;

if (fam.CanReadSignInResponse(System.Web.HttpContext.Current.Request, true))
{
    string wctxValue = this.HttpContext.Request.Form["wctx"];
}

My preference is to have the wcxt parameter represent a redirect URL (URL encoded) with your parameter as a query parameter in that so it be a URL encoded version of this:

wctx=https://yourserver/yourapp/yourpage?yourparameter=foo

Then the action that was receiving the redirect from the ACS would simply pull out the value of wctx and do a redirect to it without any more processing. This keeps things simple.

Mike Goodwin
  • 8,810
  • 2
  • 35
  • 50
  • Oh I see, so this parameter will always return after login and I can attach it to the IP url just before it goes out right? :) – Keoz Nov 27 '11 at 00:52
  • Right. It's a bit inconvenient to have to create your own IP selector page, but the sample that you can download from the ACS console is a good starting point. Good luck! – Mike Goodwin Nov 27 '11 at 00:56
  • Ok I think I get it, the wctx parameter have parameters inside so I think I have to modify this string and have my parameter there, now another newbie question is how I get this parameter back in code from the controller when the user comes back? :( – Keoz Nov 27 '11 at 03:12
  • I found this post helpful http://stackoverflow.com/questions/8240124/a-custom-login-page-for-azure-acs-not-working I think I'm close I'll dig into this stuff :) thanks – Keoz Nov 27 '11 at 04:11
  • Yes I did that thanks :) it was just a matter of passing the context to the helpers I already had that came with the sample of simple ACS for ASP.net mvc of the training kit and geting the parameter back the way you describe – Keoz Nov 29 '11 at 03:42
0

Another approach would be to save whatever data you need to pass around in the Database, and just pass around some ID that refers back to the database record. You'll pass this ID to IP and back through wctx (as Mike mentioned above).

This will solve the issue of limited length of URLs (in case your data is very large). Of course you would need to manage deletion of this data, but this shouldn't be hard.