Reputation: 6778
I want to use authentication for every action method in the application, so i add it as a global filter in FilterConfig.cs i dont use any [Authorize] attribute on controller level or any action level.If i put Authentication on controller and action level i get return url but when i put authorization on global level i dont get any return url
In my MVC project
web.config settings is bellow
<authentication mode="Forms">
<forms name="DemoApplication" loginUrl="~/Account/Login" timeout="2880" protection="All" />
</authentication>
FilterConfig syntax is bellow
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthorizationFilterAttribute());
}
AuthorizationFilterAttribute inherit AuthorizeAttribute class and override bellow method
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
filterContext.Result = new RedirectResult("~/Account/Login");
}
above code ensure me if the user is not authenticated it will be redirected to the logon page defined in the LoginUrl attribute of the forms element.During the redirection, FormsAuthentication why not append return url
AccountController Login syntax is bellow
[AllowAnonymous]
public ViewResult Login(string returnUrl)
{
//return View();
//So that the user can be referred back to where they were when they click logon
if (string.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null)
returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery);
if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl))
{
ViewBag.ReturnURL = returnUrl;
}
return View();
}
Note: here returnUrl always null
[AcceptVerbs(HttpVerbs.Post)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
authProvider.SignIn(model.UserName, false);
if (!String.IsNullOrEmpty(returnUrl))
{
if (!String.IsNullOrEmpty(returnUrl.Replace("Account", "")))
{
return Redirect(returnUrl);
}
}
//BuildUserSession(userName);
return RedirectToAction("Index", "Home");
}
else
{
return View();
}
}
Bellow is my view portion
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>Use a local account to log in.</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
}
Upvotes: 0
Views: 356
Reputation: 56909
There are several issues with your approach:
HandleUnauthorizedRequest
, you don't need to check whether the user is authenticated. That check is already done in AuthorizeCore.So, if you change your code as follows, it will work like you expect.
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthorizeAttribute());
}
Upvotes: 1
Reputation: 1407
Make sure you have included returnUrl in your view page.
@using (Html.BeginForm("Login", "Account", new { returnUrl = ViewBag.ReturnUrl }, FormMethod.Post))
{
}
Upvotes: 0