I am using Forms Authentication in my MVC 3 app and having a problem with my return URL.
When I mark an action <Authorize> on the Home controller, it redirects to the login page and works, but the return URL is then /, so when it redirects, it is redirecting to the root of the the current URL Authorize.
So the URL's are like this:
http://localhost/ - Controller = Home - Action = Index
http://localhost/Authentication/LogOn
I end up with this: http://localhost/Authentication/LogOn?ReturnURL=~%2F, I need to get back to http://localhost/
Help!! :)
Try changing your Account controllers LogOn action to something like this:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
http://localhost/Authentication/LogOn?ReturnURL=~%2F,
it means home url is duplicated
Related
I am trying to redirect back to my Home/Index page after a successful Active Directory login using PricipalContext(ContextType.Domain) to validate the credentials. I can see that the credentials are being successfully validated, however the page just seems to reload and clears out my username and password instead of redirecting to the Index page that cooresponds to my Home Controller. Everything I see implies using return RedirectToAction("Index", "Home") but doesn't seem to work for me.
web.config - You can see that it takes you to the login page by default
<authentication mode="Forms">
<forms loginUrl="~/Login" timeout="2080" cookieless="UseCookies"></forms>
</authentication>
HomeController
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
LoginController
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
string user = form["user"] as string;
string password = form["password"] as string;
string[] userInfo = user.Split('/');
if ((userInfo.Length > 2) || (userInfo.Length < 2))
{
ViewBag.Message = "You must enter Domain and Username in Domain/User format.";
return View("Index");
}
else
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, userInfo[0]))
{
bool isValid = pc.ValidateCredentials(userInfo[1], password);
if (isValid)
{
here.
return RedirectToAction("Index", "Home");
}
else
{
ViewBag.Message = "Invalid Credentials. Maximum of 3 attempts before lock out.";
return View("Index");
}
}
}
}
If you need me to provide anything else I can. I know there is somehting I am doing wrong here but I can't figure out why it keeps redirectingback to login instead of ~/Home/Index
The authorize attribute expects the form authorization cookie to be setup. When the user is successfully logged in, you need to call:
FormsAuthentication.SetAuthCookie(userInfo[1], false);
see the MSDN documentation on the signature of the method. Also a useful read: What does FormsAuthentication.SetAuthCookie do.
The following code snippet is from my ASP.NET MVC 5 application:
public ActionResult Ask(string id) {
if (!this.User.Identity.IsAuthenticated) {
string retUrl = Request.Url.AbsoluteUri;
return RedirectToAction("Login", "Account", new { returnUrl = retUrl });
}
...
}
The idea is, if the user has not yet logged in, he will be taken to the login page and subsequently be returned back to this "Ask" page.
When the user enters, for example, http://example.com/Home/Ask/12345678, method Ask() gets invoked with the correct value for id. The user is now redirected to the login page.
After Login() code in AccountController successfully authenticates the user, it calls ReturnToLocal(), passing in the url that we expect (http://example.com/Home/Ask/12345678). However, instead of invoking the Ask() method , ASP .NET somehow ends up invoking Index() method.
Appreciate your help in understanding why my redirection is broken. Regards.
Since you did not provide us neither the Login action method nor RedirectToLocal method I am assuming you are using the AccountController from MVC5 template.
If so
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
You can see that RedirectToLocal method checkes if the returnUrl parameter is 'localUrl'.
If not it does invoke Index.
In your Ask method you are passing string retUrl = Request.Url.AbsoluteUri as returnUrl which is not local (starts with http://)!
Try string retUrl = Request.Url.PathAndQuery
I'm having problem with retunUrl what is duplicating my QueryString parameters.
My url is like:
"www.mysite.com/Order/?id=1&item=123"
then, redirect me to login page and the url look like:
"www.mysite.com/login/RedirectUrl=/Order?id=1&item=123&id=1&item=123"
After the user login, the action redirect to:
"www.mysite.com/Order/?id=1&item=123&id=1&item=123"
In my page when i use Request.QueryString["id"] i got an error, because the querystring "ID" is duplicated.
My login Action code look like this:
[HttpPost]
[AllowAnonymous]
public ActionResult Index(LoginModel model, string ReturnUrl)
{
if(VerifyLogin(model))
{
if(ReturnUrl != null)
return Redirect(ReturnUrl);//redirect to url with duplicated parameters
else
return Redirect("/Home");
}
else
{
ModelState.AddModelError("", "Invalid Username or Password");
}
return View();
}
How i can solve this problem?
I think problem is in Order controller or ReturnUrl assignment logic. It might adding url+queryString. If yes you can try something like Request.Url.GetLeftPart(UriPartial.Path) + queryString
When implementing an MVC web app with FormsAuthentication, it would appear that the FormsAuthentication mechanism automagically appends ?ReturnUrl=/ to your mvc routes. I did notice, though, that the default web application which MVC 3 provides out of the box implements FormsAuthentication but does not appear to suffer from the appended ReturnUrl=/ problem. I've looked through the code and can't see where this is being handled. Anyone know?
In the LogOn action of the AccountController, you'll see that if a return url is present, the user will be redirected to it after a successful log on:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Try adding the [Authorize] attribute to the Action or controller. This will generate the url needed to redirect after login.
I have two types of roles [Admin, HelpDeskAdmin].
I have a single logon view(both users go to same link to login) and I want to check their role once logged in and redirect to their respective admin pages once authenticated. The code below doesn't identify the logged in user as being in the role the first time and reloads the logon page, the second time they logon it redirects correctly.
Does this have something to do with the authentication cookie not being in place when it checks the first time? How could I accomplish this scenario?
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
if (Roles.IsUserInRole("Admin"))
{
//go to admin landing page
return RedirectToAction("Index", "Manage");
}
else if (Roles.IsUserInRole("HelpDesk"))
{
//go to helpdesk landing page
return RedirectToAction("Index", "Interview");
}
else /******FIRST TIME THROUGH IT ALWAYS GOES HERE *******/
return RedirectToAction("Index", "Home"); //not in any of those roles
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
The user is technically NOT logged in until the next request is handled and the Authenication Cookie is set....
Either do the redirection logic in another Action method or perhaps extract the user info using Roles.IsUserInRole(model.UserName, "Admin") [[Note specifying the username]] from within this Action.