FormsAuthentication Redirect prevent data loss

C

Chuck

I have a forms authentication website that has a page where users spend a
lot
of time on. So somebody spends an hour on the page and then presses submit
and gets redirected to the logon page. Followed by a redirect back to where
they were minus all the data they typed in.

Is their a way to handle time outs without loosing data on the redirect.
Maybe popup a logon page versus a redirect or something.

I already have a httpmodule looking at the authenticate and endrequest
events. To fix problems associated with the basic forms authentication
design. So I don't mind coding low level stuff.

I can not violate security associated with ticket time outs by disabling the
timeout or doing javascript postbacks.
 
A

Allen Chen [MSFT]

Hi,
Is their a way to handle time outs without loosing data on the redirect.
Maybe popup a logon page versus a redirect or something.

There's no good way to know this. In your another post I think Alexey
Smirnov's suggestion a good way to solve this issue if you want enable the
timeout. You can store data in cookie (client side) or database (server) or
other places where the client can access later.

If you need a simple workaround, I think you can use JavaScript to popup a
new window to temporarily save data. If the timeout is 10 minutes you can
pop up a window after 9 minutes.

In main page, call this JS to popup window:

<script type="text/javascript">
function Popup()
{

var w = window.open("NewWindow.aspx?data=" +
document.getElementById("testinput").value);
}

</script>

<input id="testinput"></div>

Use settimeout if needed:

http://www.w3schools.com/htmldom/met_win_settimeout.asp

In the popup window, call this JS to fill data back:

<script type="text/javascript">
function FillData() {

window.opener.document.getElementById("testinput").value =
GetQueryString("data");
}
function GetQueryString(ji) {
hu = window.location.search.substring(1);
gy = hu.split("&");
for (i = 0; i < gy.length; i++) {
ft = gy.split("=");
if (ft[0] == ji) {
return ft[1];
}
}
}

</script>
<input onclick="FillData();" value="Fill Data" />

Please let me know if it can resolve this issue and feel free to ask if you
have additional questions.

Regards,
Allen Chen
Microsoft Online Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

Chuck

I can't use the suggestions that violated security principles like having
cookies/tokens which are set to expire for security reasons, not expire by
having javascript refreshes.

Are their any other complicated solutions which would involve examining the
http pipeline events.
 
J

Jesse Houwing

Hello Chuck,
I can't use the suggestions that violated security principles like
having cookies/tokens which are set to expire for security reasons,
not expire by having javascript refreshes.

Are their any other complicated solutions which would involve
examining the http pipeline events.

You could store the whole request in memory or database, before the runtime
decides that the login sessionhas timed out (so pretty early in the request
lifecycle). Then redirect to the original page, substitute the request data
from memory and let the page do its usual thing

As you say, it migth require some very low level hacking, but should work.

Other solutions might include (in random order):
- split up the page in multiple steps, storing the results in between.
- post back on a timer, storing results as the user types, you could detect
that the postback hasn't changed between previous postbacks and still logout
the user
- use ASP.NET Ajax to send the changes to the server in the background
- use a client side object and use the local Isolated Storage facility
- use Silverlight and store the data in the local data store
- set the timeouts on session and login very high and keep a last action
timer in the session. handle the page as usual, but the log out the user
if x amount of time has expired (this can be handled from the global.asax)
- use a javascript timeout on the page to warn the user that the session
will terminate in x minutes and let him push an intermediate save button
- educate the users on how 'the web usually works'
- ...
- ...
 
A

Allen Chen [MSFT]

Hi,
I can't use the suggestions that violated security principles like having
cookies/tokens which are set to expire for security reasons, not expire by
having javascript refreshes.

Have you tried my suggestion that uses JavaScript to popup a window to
store data before timeout? I believe it'll not violate anything. It's just
a helper window for user to fill back data later if needed. After seeing
the same page user can click the button on the popup window to fill data
back to the form.
Are their any other complicated solutions which would involve examining
the http pipeline events.

As far as I know it's difficult to know whether the redirect is from the
authentication module so this approach cannot work.

Jesse has provided almost all the possible solutions to this issue. If you
don't want to store data at server side you can use Silverlight to store
data to isolated storage:

http://msdn.microsoft.com/en-us/library/bdts8hk0(vs.95).aspx

And you need to interact with your page (data retrieved from isolated
storage to Silverlight app and then to HTML DOM elements):

http://msdn.microsoft.com/en-us/library/cc645076(VS.95).aspx

With the help of Silverlight you can easily implement auto save function.

Please let me know if it can meet your requirement and feel free to ask if
you have additional questions.

Regards,
Allen Chen
Microsoft Online Support
 
A

Allen Chen [MSFT]

Hi Chuck,
I can't use the suggestions that violated security principles like having
cookies/tokens which are set to expire for security reasons, not expire by
having javascript refreshes.
Are their any other complicated solutions which would involve examining the
http pipeline events.

Have you solved this issue?

Regards,
Allen Chen
Microsoft Online Community Support
 
A

Allen Chen [MSFT]

Hi,

Thanks for your reply. From your description:
I can't use the suggestions that violated security principles like having
cookies/tokens which are set to expire for security reasons, not expire by
having javascript refreshes.

I think your concern is, you don't want JavaScript to refresh your page.
But my suggestion doesn't refresh the page. JavaScript is used to pop up a
window. I repaste the code here:

If you need a simple workaround, I think you can use JavaScript to popup a
new window to temporarily save data. If the timeout is 10 minutes you can
pop up a window after 9 minutes.

In main page, call this JS to popup window:

<script type="text/javascript">
function Popup()
{

var w = window.open("NewWindow.aspx?data=" +
document.getElementById("testinput").value);
}

</script>

<input id="testinput"></div>

Use settimeout if needed:

http://www.w3schools.com/htmldom/met_win_settimeout.asp

In the popup window, call this JS to fill data back:

<script type="text/javascript">
function FillData() {

window.opener.document.getElementById("testinput").value =
GetQueryString("data");
}
function GetQueryString(ji) {
hu = window.location.search.substring(1);
gy = hu.split("&");
for (i = 0; i < gy.length; i++) {
ft = gy.split("=");
if (ft[0] == ji) {
return ft[1];
}
}
}

</script>
<input onclick="FillData();" value="Fill Data" />


Please let me know if this is not what you need and tell me what the
problem of this approach is so that I can try to think of another possible
solution.

Regards,
Allen Chen
Microsoft Online Support
 
C

Chuck

I think we are at a big disconnect.
I can't do anything that would violate security principles. Such as posting
back every five minutes or so. Doing something like putting all the form
variables into an array probably wouldn't work on forms that have grids and
other complicated controls.

I'll try to see how other websites like the banking sites do it.
 
A

Allen Chen [MSFT]

Hi,
I think we are at a big disconnect.
I can't do anything that would violate security principles. Such as posting
back every five minutes or so. Doing something like putting all the form
variables into an array probably wouldn't work on forms that have grids and
other complicated controls.

Yes I understand your concern. But my suggestion doesn't do any postback.
It opens a new window using JavaScript for user to

fill back data. Could you try it and let me know what the problem of my
suggestion is? If you put TextBox in GridView it's

also possible to do this. Below is revised code:

Default.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//
{
GridView1.DataSource = "Hello World";
GridView1.DataBind();
}
}

protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("AnyPage.aspx");
}


Default.aspx:


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script type="text/javascript">
function AddToArray() {
window.myarray = document.getElementsByTagName("INPUT");

}

function Popup() {

var w = window.open();
w.document.write(
"<html><body>" +
"<script type='text/javascript'>" + " function IDValuePair(id,
value,type) {this.id = id;this.value =

value;this.type=type;}" +
" window.backuparray=new Array();for (var i = 0; i <
window.opener.window.myarray.length; i++)

{window.backuparray = new
IDValuePair(window.opener.window.myarray.id, window.opener.window.myarray

.value,window.opener.window.myarray.type);} " +
"function FillData() { for (var i = 0; i < window.backuparray.length; i++)
{" +
"if(window.backuparray!=null)" +
"var
element=window.opener.window.document.getElementById(window.backuparray.i
d);if(element!=null&&window.backuparray

.type=='text'){element.value = window.backuparray.value;}" +
"}}" +
"</scrip" +
"t>" + "<input type='button' onclick='FillData();' value='Fill
Data'/> </body></html>");

}



</script>
</head>
<body onload="AddToArray();">
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" Text="Normal
TextBox"></asp:TextBox>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text="TextBox in
GridView"></asp:TextBox>
</ItemTemplate></asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button OnClientClick="Popup()" ID="Button1" runat="server"
Text="ClickMe to Simulate Session Timeout. In real case please
use JavaScript settimeout to pop up window"
onclick="Button1_Click"/>

</div>
</form>
</body>
</html>


AnyPage.aspx.cs:

protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("Default.aspx");
}


AnyPage.aspx:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
Go Back to original page and click the button on the popup window to
fill data back.
<asp:Button ID="Button1" runat="server" Text="Go Back"
onclick="Button1_Click" />
</div>
</form>
</body>
</html>

Another option is:

Store data in cookie or Silverlight's local storage every few minutes, to
create an auto-save effect. The data is stored in

client side so it doesn't need a postback to make it work.

Please let me know which option you prefer most. I could give you code
snippet to test.

Regards,
Allen Chen
Microsoft Online Support
 
A

Allen Chen [MSFT]

Hi,
I think we are at a big disconnect.
I can't do anything that would violate security principles. Such as posting
back every five minutes or so. Doing something like putting all the form
variables into an array probably wouldn't work on forms that have grids and
other complicated controls.

Can my suggestion solve this issue?

Regards,
Allen Chen
Microsoft Online Support
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top