Rewriting Url in ASP.Net MVC - c#

I am struggling over this issue since yesterday.I am working on a web application which includes email service.Email includes 'link' to a certain page of that application.
Now:I have 2 scenarios:
1) If the user is logged in(in the application) already and he hit
the url he got in his email,the link will open perfectly.
2) If the user is not logged in(in the application) then the url
will not open and will redirect itself to the login page with the
functionality added in the BaseController.
*
Now what I want is when the user logs in after hitting the url and on
successfully login the user gets redirect to the link provided in the
Email.
*
for eg: If the user gets an email to the detail page of an employee,So on successfully login the user gets redirect to the Detail page of the employee.
Something like appending the redirecturl to the login page.
I think rewriting url is what I should be doing.
But I dont know how can I use that in this case.Help me out.

The default project template that comes with ASP.NET MVC 5 behaves exactly as you describe.
If you want to redirect to a custom login URL, reconfigure the LoginPath property of the CookieAuthenticationOptions object
LoginPath = new PathString("/Account/Login")
In the default template this is done in the Startup.Auth.cs class.
NOTE: If you are using an old version of ASP.NET MVC, the default project template behaved in the same way. But previously this was implemented using Forms Authentication, so in order to redirect to a custom login URL you would then have to set the loginUrl attribute of the <forms> tag in the Web.config file

By default if a user tries to access the authorized page when he is not authorized the automatically gets redirected to the log in page or the page which is configured in web.config file for the element. And you can see the query string returnUrl having the url that was tried to access initially get appended to the log in url.
To access the return url, include a new parameter as returnUrl and maintain the return url in a hidden field by model data to access on post back for redirection.
If the user is authenticated then on post back then redirect the user to the specified page what he intended to go for.

I don't remember exactly but few month ago I implemented similar functionality and i had to save returnUrl explicitly (due to MVC bug or something) - Refer this link
AccountController.cs - Snapshot
[HttpGet]
[AllowAnonymous]
public ActionResult Login(string returnUrl, string userName)
{
// You login method logic....
// Add this line to save the returnUrl value
ViewBag.ReturnUrl = returnUrl;
}
Login.cshtml - Snapshot
#using (Html.BeginForm("Login", "Account", FormMethod.Post ,new {ReturnUrl = ViewBag.ReturnUrl}))
{
<input type="hidden" name="ReturnUrl" value="#Request.QueryString["ReturnUrl"]" />
// .....
}
See if this helps in your case.

Related

RedirectToAction appends route to URL instead of directing to action in other controller

I have a simple RedirectToAction at the end of a controller method in the controller "AccountController". I want to redirect now to a method called loads in the Home controller. Code:
return RedirectToAction("loads", "Home", new { unique_id = new_questionnaire.Unique_ID, purpose = "resume" });
Instead of going to http://localhost:40829/Home/loads/..., it goes to http://localhost:40829/Home/Index?ReturnUrl=%2fHome%2floads%3funique_id%3d49557%26purpose%3dresume&unique_id=49557&purpose=resume. What am I doing wrong here? How can I redirect to another controller method while passing route values as well?
The problem was that I use Forms Authentication and the user was not authenticated when trying to access the URL. This caused the website to redirect the user to the login page.
When ReturnURL shows up in the url, this might be the problem. Hope this can help people in the future.
In my case, adding a Cookie and a Forms Authentication Ticket solved the problem. I already had a function ready for this, I just needed to call it.

The anti-forgery cookie token and form field token do not match.Error After Release [duplicate]

I'm using the default login module in ASP.NET MVC 4. I did not change any code in the default application and i hosted it on a shared server.
After i logged in using default login page. i kept the browser idle for some time. Then obviously application redirected to the login page when i try to perform any controller action with [Authorize] attribute.
Then i try to login again and it gives an error when i click on login button.
The anti-forgery cookie token and form field token do not match.
LogIn action
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
I resolved the issue by explicitly adding a machine key in web.config.
Note: For security reason don't use this key. Generate one from https://support.microsoft.com/en-us/kb/2915218#AppendixA. Dont use online-one, details, http://blogs.msdn.com/b/webdev/archive/2014/05/07/asp-net-4-5-2-and-enableviewstatemac.aspx
<machineKey validationKey="971E32D270A381E2B5954ECB4762CE401D0DF1608CAC303D527FA3DB5D70FA77667B8CF3153CE1F17C3FAF7839733A77E44000B3D8229E6E58D0C954AC2E796B" decryptionKey="1D5375942DA2B2C949798F272D3026421DDBD231757CA12C794E68E9F8CECA71" validation="SHA1" decryption="AES" />
Here's a site that generates unique Machine Keys:
http://www.developerfusion.com/tools/generatemachinekey/
Another reason for having this error is if you are jumping between [Authorize] areas that are not cached by the browser (this would be done on purpose in order to block users from seeing protected content when they sign out and using the back button for example).
If that's case you can make your actions non cached, so if someone click the back button and ended up on a form with #Html.AntiForgeryToken() the token will not be cached from before.
See this post for how to add [NoCache] ActionFilterAttribute:
How to handle form submission ASP.NET MVC Back button?
make sure you put the #Html.AntiForgeryToken() in your page's form
I had this problem for a long time and assumed it was something wrong with ASP.NET.
In reality, it was the server. I was with WinHost then, and they have a 200MB memory limit. As soon as I had ~20 users on at the same time, my limit was reached. At this point, everyone was logged out and yielded these issues.
For me, this was caused by submitting a form using a button tag. Changing this to an input submit tag resolves the issue.
In My case "We found that the Site cache was enabled and due to this “anti-forgery” token value was not updating every time, after removing this cache
form is submitting."
In my case it was related to multiple cookie values set by domain site and subdomain site.
main.com set __RequestVerificationToken = 1
sub.main.com set __RequestVerificationToken = 2
but when request to sub.main.com was sent it used __RequestVerificationToken = 1 value from main.com

How to resolve: The provided anti-forgery token was meant for a different claims-based user than the current user

I am getting this error:
The provided anti-forgery token was meant for a different claims-based user than the current user.
and I am not sure how to correct this..
I have a MVC5 site and in this site I have a login page.
This is the scenario that it occurs on.
User AAA logs in. (No issues)
I attempt to access a view where the user does not have access.
I have the class decorated with an Authorize(Roles="aa")
The view then logs the user off and puts them back to the login page.
User AAA logs in. (This time I get the error mentioned above)
To note:
I am using customErrors and this is where I see the error message.
When I log the user out I am running this method:
[HttpGet]
public void SignOut()
{
IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
authenticationManager.SignOut(MyAuthentication.ApplicationCookie);
}
Could I possibly be missing something on the SignOut?
UPDATE:
This only occurs because of step #2 listed above.
If I log in, then log out (calling same code) then log back in, then I do not have this issue.
I think you've neglected to post some relevant code. The Signout action you have returns void. If you were to access this action directly in the browser, then the user would get a blank page after being signed out with no way to progress forward. As a result, I can only assume you are either calling it via AJAX or calling as a method from another action.
The way anti-forgery works in MVC is that a cookie is set on the user's machine containing a unique generated token. If the user is logged in, their username is used to compose that token. In order for a new cookie, without a username to be set, the user must be logged out and a new request must occur to set the new cookie. If you merely log the user out without doing a redirect or something, the new user-less cookie will not have been set yet. Then, when the user posts, the old user-based cookie is sent back while MVC is looking for the new user-less cookie, and boom: there's your exception.
Like I said, you haven't posted enough code to determine exactly why or where this is occurring, but simply, make sure there is a new request made after logging the user out, so the new cookie can be set.
I was able to reproduce by clicking on the login button more than once before the next View loads. I disabled the Login button after the first click to prevent the error.
<button type="submit" onclick="this.disabled=true;this.form.submit();"/>
Disable the identity check the anti-forgery validation performs. Add the following to your Application_Start method:
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true.
try:
public ActionResult Login(string modelState = null)
{
if (modelState != null)
ModelState.AddModelError("", modelState);
return View();
}
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model)
{
AuthenticationManager.SignOut();
return RedirectToAction("Login", "Controller", new { modelState = "MSG_USER_NOT_CONFIRMED" });
}
I haved similar problem. I found this text "#Html.AntiForgeryToken() " in my project in 2 place. And one plase will was in "view file" Views - test.cshtml.
#using (Html.BeginForm())
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
#if (#Model.interviewed)
...
I deleted this code line ("#Html.AntiForgeryToken() ") and working fine.
PS: But I am not delete this code in file _LoginPartial.cshtml.
Good luck!

Notify user of inadequate role ASP.NET MVC 4 simplemembership simplerole

I am using ASP.NET MVC4 SimpleMembership and SimpleRoleProvider to determine authorization before exposing certain methods.
For example:
[Authorize(Roles = "Admin,Corporate")]
public ActionResult Edit(int id = 0)
{
//some code
return View(model)
}
If the user is not in the "Admin" or "Corporate" role (or their session has expired), they are correctly sent to the /Account/Login page.
However, one tester brought up a good point that once on this Login page, there is no hint as to why the user was sent here. If they simply aren't authorized to access the page they are trying to access, they keep logging in again and again and thinking the site is broken.
Ordinarily, I would add a property to the model or pass an optional parameter in the url with a message such as,
You do not have adequate permissions to access that page.
Please log in as an administrator.
or something to that effect. However, because the filter happens before they enter the method, where / how would I add the message?

Logging in with a ReturnUrl pointing to a POST action: FAIL!

I have an Asp.Net MVC project with the typical forms authentication that redirects the user to a page upon successful login. If there is a ReturnUrl in the querystring it will redirect the user to the ReturnUrl.
Problem comes when a logged in user sits on a page long enough for their login to time out and then submits the form causing a post to the server. Since the user is now no longer authenticated it'll force the user to log in again. However the ReturnUrl would point to an action that only accepts the POST method and would throw an exception after being redirected.
Is there a work around for this?
You have to create an identical GET action and redirect it back to the form they were filling out. The problem is that the redirect to the ReturnUrl is doing a GET, not a POST, hence the error.
Example:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SomeFormAction()
{
//redirect them back to the original form GET here
RedirectToAction(stuffhere);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SomeFormAction(FormCollection collection)
{
//this is your original POST
}

Categories