Setting TempData within a ActionFilterAttribute - c#

I have a custom action filter, that inside the OnActionExecuting, depending on certain criteria, logs out a user and redirects them to the home page of the site. The (stripped back) code for the redirect part is below
filterContext.Controller.TempData.Add("key", "Message");
filterContext.Result = new RedirectResult("/");
As above, i am also setting a tempData message. Because the user has been logged out, when they hit the home page, the [Authorize] attribute will redirect them to the login GET page. On the login view, i am displaying any messages from within tempData. However in this situation the tempData is empty.
This is very similar behavior to how my login POST works (if invalid, it redirects to home, which redirects to login and displays the tempData message that was set in the Login post). This code can be seen below
TempData.Add("key", errorMessage);
return Redirect("/"));
The reason i am doing it this way, rather than redirecting specifically to the login page is because this code is distributed across many sites, so we dont know what the login GET url is.
Does anyone have any information as why this is working for the Login POST but not for the ActionFilter Redirect?
Edit:
If i remove the logout call within the custom action filter, the tempData is still set within the Home action - however this doesnt explain why it works for the Login POST but not the action filter?

So it turns out that when i was logging out the user from the system, i was also abandoning the session (calling HttpContextBase.Session.Abandon()) and also resetting the cookie session id. These were affecting the TempData behavior. By removing these calls, the tempData is now correctly set and displayed.

setting the result to new RedirectResult("/") will cause the current server-processing to stop ,and send the client a responce, that tells the client to request a new URL - the one you had said in the RedirectResult. The second request is then different, and does not contain the values from the previous processing.
Try using Redirect("/"); or Server.Transfer("/"); to service the new route in the same client request.

Related

.ASPXAUTH Cookie Not Found in Request.Cookies

I am creating a web application that is hosted under a web site with forms authentication enabled. I have a role in my authentication database "Admins". Here is my controller code:
[RequireHttps]
[Authorize(Roles = "Admins")]
public ActionResult Index()
{
return this.View();
}
When I go to the Index page, if I'm not authenticated, it redirects me to the login page where I enter my credentials. The login page then redirects back to Index page of the new app, but the controller doesn't recognize that the user is authenticated.
I have taken the Authorize attribute off and looked at the request as it went out in the Chrome developer console and confirmed that the cookie is indeed being sent. But if I leave the Authorize attribute as is, and go to the Index page, the cookie collection on the request in my controller is empty. The headers collection contains a header entitled "Cookie", and the value of the header contains the .ASPXAUTH cookie.
The login page calls logs in with this code:
FormsAuthentication.SetAuthCookie(userName, remember, "/");
This behavior is reproducible in all major browsers.
What can I do to cause the Cookies collection of the request to be populated?
What do I need to do to make the application realize that the user really is authenticated?
Edit:
I still don't have it working, but I'm pretty sure it's something to do with the ASPXAUTH cookie being filtered.
I'm sure there are multiple causes of this problem. In my case, the problem was that the version of MVC I was using to write the cookie was different from the version that was decrypting it. I changed my sites to all be running MVC 4, and the cookie that was created by one site was consumable by the other site.
Is the .ASPXAUTH cookie generated a secure cookie, i.e. SSL? If so and your Index.aspx is only over HTTP not HTTPS, you will not see the cookie in the collection.

How to maintain URL that user entered

My iis folder structure is like
Default Web Site---->online and Accessing with www.sitename.com/online
Default Web Site---->trade and Accessing with www.sitename.com/trade
Default Web Site---->private and Accessing with www.sitename.com/private
Here the login page is residing inside "Default Web Site---->trade/Login.aspx".When user enter
www.sitename.com/online or www.sitename.com/private or www.sitename.com/trade he/she will be redirecting to the url www.sitename.com/trade/Login.aspx.
So my need is when user enter "www.sitename.com/online" he/she should remain in the same URL as www.sitename.com/online and not "www.sitename.com/trade/Login.aspx".So how can i maintain the URL that user entered.
Thanks,
Joby
Best way to do this is pass a parameter w/ original url in your redirect to login page, and then have login redirect you back to that original url
Location: http://example.com/login?ref=http%3A%2F%2Fexample.com%2Ffoo
Then after login, you read "ref" parameter and do a location redirect back.
If you are using built-in membership provider, then you may use [Authorize] attribute, that has an functionality to redirect the user to original page, after user gets authenticated system will automatically redirect the user to requested page.
Or you may try following solution:
Something like this:
www.sitename.com/trade/Login.aspx?ReturnUrl=http%3A%2F%2Fsitemap.com%2Fonline
After user gets authenticated, you may redirect the user to requested page.
Response.Redirect(Request.QueryString["ReturnUrl"]);
Consider using MVC or at least routing portion of it with ASPX pages to render views. This way you can have any Urls you want unrelated to physical file names.
Users rarely enter any urls... and I'm not really sure anyone cares as long as Url makes some sence (or complete noncense). So I think it is perfectly ok to render login page at something like /login and than redirect back to originating page. You can save original url in query string (as #chovy suggests) or hidden element on the page if login never leaves your site. If login leaves your site (i.e. for OAuth authentication) thatn session state or cookies may be place to store return Url.

ASP.net MVC - Authorize with Windows Authentication/Role Provider

I am using Windows Authentication in my MVC application with the WindowsTokenRoleProvider. I created a controller action that looks like:
[Authorize(Roles=#"Fake\Role")]
public ActionResult Admin()
{
return View();
}
When I try and hit this page I see a blank page. Is there a way for me to display a custom view that says "You are not authorized to view this page" isntead of just showing a blank page. If I was using forms authentication then it would redirect me to the login page, but that doesn't really make sense for Windows Authentication since you never really log in specifically.
You most likely are not getting a blank page (I'm not absolutely certain). You are most likely getting a http response that has no content, but has a 403 not authorized status code.
Assuming this is accurate, all you need to do is setup in ASP.NET custom errors (and IIS custom errors) is a redirect rule for 403 codes to the appropriate page.

Why HttpContext.Current.Session is changing evertime I visit the same page ASP.Net

Here's the scenario
I have a page lets say login.aspx having a button called login, on click event of that button when I check for the SessionID its shows a specific value for example "A"
Now I am making a call to some external page and that page then calls this page again.
for instance once I click login button I call a twitter app and when user authorizes it, I am redirected back to the same page, but now when I am accessing the SessionID its a new ID.
I have no idea why this is happening, I just want to have the same SessionID
Are you adding any data to the session? You need to do so for the session ID to "stick".
You don't have multiple web servers, do you?
If so, and if you're not using a shared session state provider, you'd tend to see this kind of behaviour.
Edit.
OK, next question...
Is the URL that the Twitter authorisation is returning to using exactly the same domain name?
For example, if your application is running on http://127.0.0.1:1234/ and the return URL is http://localhost:1234/ ?
Edit2: Yes?
When you are redirected back from the Twitter app on 127.0.0.1, the ASP.NET session cookie isn't being passed back to the web server because the domain is different.
You need the domain that the app is running under to match the Twitter callback URL.
Reconfigure the Twitter callback URL to localhost:1234 and I think you should be OK.

How can I redirect a user back to signout page when timed out? Asp.net MVC

I have site that users lots of ajax(jquery). Now if the user times out for whatever reason(walked about for 30mins or something). On there next action I want them to be returned to the login page.
I setup everything in the webconfig(returnUrl and timeout) and if they try to go to a page they have no premission to go to they get sent to the login page.
However I have the authorize tags on the methods in my controllers that are used for ajax requests. So if a user timesout they are no longer authenticated but they might be on that needed authentication since they logged in and walked away.
Now they could go and try to save something at this point that would do an ajax request. The authorize tag will stop them from doing this since they will fail authorization and the return url will kick in.
However eventhough the return url seems to be sent back to them they are not redirected to the signin page. So I am guessing since all this stuff is ajax thats why it is not working properly. So is there away I can fix this?
You need to check the Ajax error for a 403 response
Run a client-side function every 30 seconds using setTimeout, which should ask the server via AJAX if the session has been timed out. If it has, the client-side code could toss out any login cookie and redirect to the login page.
You can either code hard-code the login url into the client-side code, or have the server handler return the value from the web.config if it needs to timeout.
This still leaves the possibility that the user could try something in the 0-30 seconds between when the user actually times out and the client side code does its request to check. To prevent this as well, have the server send back the amount of time left in the session, that way your client-side code can make the decision to either check back again sooner, or do the client-side redirect before the server-side drop-dead time.

Categories

Resources