Require login before doing a action - asp.net-mvc

Thank everyone read my topic. But i need your help !
I've got a problem with Asp.NET MVC Action.
In HomePage. I have a link redirect to an action call checkTicket(), but require login.
So, in checkTicket() method. I'm using following code to check permision
if (Request.IsAuthenticated)
{
return View();
}
else
{
return RedirectToAction("Login", "Account");
}
But in action Login of Account controller. How can i return back to checkTicket's View() ?
This is something i want.
HomePage (click) -> checkTicket (require) -> Login (return) -> checkTicket()

Create a cookie that is set, letting you know that the user wants to checkticket but is not logged in:
if (Request.IsAuthenticated)
{
return View();
}
else
{
//The cookie's name is UserSettings
HttpCookie myCookie = new HttpCookie("UserSettings");
//The subvalue of checkticket is = true
myCookie["checkticket"] = "true";
//The cookie expires 1 day from now
myCookie.Expires = DateTime.Now.AddDays(1d);
//Add the cookie to the response
Response.Cookies.Add(myCookie);
return RedirectToAction("Login", "Account");
}
Then in your Login Action, check if the cookie exists like so:
if (Request.Cookies["UserSettings"] != null)
{
string userSettings;
if (Request.Cookies["UserSettings"]["checkticket"] != null)
{
userSettings = Request.Cookies["UserSettings"]["checkticket"];
}
if(userSettings) {
//redirect to checkticket
} else {
// redirect to your normal view
}
}
*Code courtesy of MSDN: write cookie, read cookie

Related

ASP.NET MVC : calling a controller from another controller

I am writing a web application with ASP.NET MVC, and I would like to call a controller from another controller. More precisely I would like to call a routine in the Login controller, where I do sign in and sign out, from the controller where I allow the normal user to change his/her password. Thus, I check the old password (given by the user in the change password form).
I tried to search in the internet methods to change user (not Administrator) password but I didn't find anything good.
Thank you.
I didn´t called a controller from another controller, instead I called my User Administration Controller AdminController from a View within the HomeController controller (via na input button).
Then the code of my routine EditByUser in the AdminController was written as:
[HttpPost]
[Authorize]
public async Task<IActionResult> EditByUser(string email, string passwordnew, string passwordconf)
{
AppUser user = await userManager.FindByEmailAsync(email);
if (user != null)
{
IdentityResult validEmail
= await userValidator.ValidateAsync(userManager, user);
if (!validEmail.Succeeded)
{
AddErrorsFromResult(validEmail);
}
IdentityResult validPassnew = null;
bool passNewEqPassConf = passwordconf == passwordnew;
if (!passNewEqPassConf)
{
ModelState.AddModelError("", "New Password not equal to Confirmation!");
}
if (!string.IsNullOrEmpty(passwordnew) && passNewEqPassConf)
{
validPassnew
= await passwordValidator.ValidateAsync(userManager, user, passwordnew);
if (validPassnew.Succeeded)
{
user.PasswordHash = passwordHasher.HashPassword(user, passwordnew);
}
else
{
AddErrorsFromResult(validPassnew);
}
}
if (((validEmail.Succeeded && validPassnew == null)
|| (validEmail.Succeeded
&& passwordnew != string.Empty && validPassnew.Succeeded)) && passNewEqPassConf)
{
IdentityResult result = await userManager.UpdateAsync(user);
if (result.Succeeded)
{
return RedirectToAction("Index", "Home", new { email = user.Email });
}
else
{
AddErrorsFromResult(result);
}
}
}
else
{
ModelState.AddModelError("", "User not found!");
}
return View(user);
}
However, I didn't manage to check the old password… The sign in is made on another controller…

Windows Authentication Logout / SigninwithDifferent User

I am using windows authentication in ASP.NET MVC.
I want to Logout? So I researched and found the following
The code is based on decompiling the Microsoft.TeamFoundation.WebAccess which has the "Sign in as a different User" function.
public ActionResult LogOut()
{
HttpCookie cookie = Request.Cookies["TSWA-Last-User"];
if(User.Identity.IsAuthenticated == false || cookie == null || StringComparer.OrdinalIgnoreCase.Equals(User.Identity.Name, cookie.Value))
{
string name = string.Empty;
if(Request.IsAuthenticated)
{
name = User.Identity.Name;
}
cookie = new HttpCookie("TSWA-Last-User", name);
Response.Cookies.Set(cookie);
Response.AppendHeader("Connection", "close");
Response.StatusCode = 0x191;
Response.Clear();
//should probably do a redirect here to the unauthorized/failed login page
//if you know how to do this, please tap it on the comments below
Response.Write("Unauthorized. Reload the page to try again...");
Response.End();
return RedirectToAction("Index");
}
cookie = new HttpCookie("TSWA-Last-User", string.Empty)
{
Expires = DateTime.Now.AddYears(-5)
};
Response.Cookies.Set(cookie);
return RedirectToAction("Index");
}
Is the above code reliable?
ANd how to redirect to another page like logout succesful
after response.clear??

Redirect to actionmethod/view

I have implemented idel time out functionality. Here when the user is idel for 1 min, we redirect the user to login page. We have kept the track of the url that the user was when the auto logout happened. Eg , of the user is on reset password view and if the auto logout happens the url which i get is as follows
http://localhost/XYZ.Portal/?returnUrl=%2FXYZ.Portal%2FUser%2FResetPassword
the above url is achieved by using the following code
'#Url.Action("Login", "User", new { returnUrl = HttpContext.Current.Request.RawUrl })'
Now when the user logs in again as he is redirected to login page, I am using the following code to redirect him back but the code doesnt seem to work. What am I doing wrong.?
[HttpPost]
public ActionResult Login(FormCollection formCollection)
{
if (ModelState.IsValid)
{
UserBE user = new UserBE();
user.Email = formCollection["Email"];
user.Password = formCollection["Password"];
user = UserBL.AuthenticateUser(user);
if (user.AuthenticUser)
{
if (Request.QueryString["returnUrl"] != null)
{
string returnUrl = Server.UrlDecode(Request.QueryString["returnUrl"]);
Redirect(returnUrl );
}
else
{
Session["Email"] = user.Email;
return RedirectToAction("DashBoard");
}
}
else
return View(user);
}
return View();
}
[HttpGet] login action method:
[HttpGet]
public ActionResult Login()
{
return View();
}
returnUrl I get as XYZ.Portal/User/ResetPassword
Thanks In advance.
You need to return the RedirectResult:
if (Request.QueryString["returnUrl"] != null)
{
string returnUrl = Server.UrlDecode(Request.QueryString["returnUrl"]);
return Redirect(returnUrl);
}
See RedirectResult
Not working. Now my URL becomes localhost/XYZ.Portal
In this case you can do 1 of 2 options:
1) Write:
string startReturnUrl = "http://www." + your returnUrl
or
2) split your returnUrl like:
string viewName = returnUrl.Split('/').Last();
But I think better change returnUrl to just only Name of View that you need

Alter does not working before redirect + controller MVC

I have code:
public ActionResult Inner(simpleQA.Models.Post model)
{
if(simpleQA.User.Current != null)
{
simpleQA.Post objPostAns = new Post();
objPostAns.TypeId = 4;
objPostAns.Content = model.ContentAnswesr;
objPostAns.RelatePostId = model.RelatePostId;
objPostAns.CreateAt = DateTime.Now;
objPostAns.CreateBy = simpleQA.User.Current.Id;
objPostAns.Save();
return View("");
}
else
{
Response.Write("Please Login");
Response.Redirect("/");
}
return View("/");
}
I try Respon.write alter before redirect but it does not working.
Tell me one alter.
You can't use response.write in an MVC controller. The controller can only pass data to the view.
What you should do instead of Response.Redirect is redirect to a login View:
return RedirectToAction("Login");
(better use built in (forms)authentication because it'll send the user to the login form automatically and after login back to the page he meant to go to)

How can I change the ASP.Net MVC Login Redirect based on role?

I have the following code I've typed into the Account Controller in my MVC project and I am in both the administrator and manager roles. When I log in I get redirected back to my home index instead of being redirected to my AdminApp index. Any ideas where I'm going wrong in my code?
[AcceptVerbs(HttpVerbs.Post)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
{
if (!ValidateLogOn(userName, password))
{
return View();
}
FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
if (User.IsInRole("Administrator") || (User.IsInRole("Manager")))
{
return RedirectToAction("Index", "AdminApp");
}
else
{
return RedirectToAction("Index", "Home");
}
}
}
The reason your code is not working as expected is because the User has technically not been signed in and authenticated yet. Say what? But you did call SignIn!
FormsAuth.SignIn(userName, rememberMe); - which in this case is just a wrapper for FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); - only sets the asp.net authorization cookie on the users browser as part of the response. It is only for requests after this point that the user's browser will have the cookie, causing the asp.net membership to properly set up the 'User' object. All of your code in the LogOn method is still assuming an anonymous user, so your IsInRole check fails and you are redirected home. Put your if statement on another page and after you've signed in, you'll see that now User.IsInRole works as expected. (And indeed, this is what you'd use User.IsInRole for, just not during the logon process)
So how to check during the actual logon process? Roles.IsUserInRole or Roles.GetRolesForUser are a couple of ways, eg.:
if (Roles.IsUserInRole(userName, "Administrator") || Roles.IsUserInRole(userName, "Administrator"))
{
return RedirectToAction("Index", "AdminApp");
}
You must explicitly specify the user name of the user logging in, which will actually execute a query against the membership datastore. On that note, I believe the above code would as a result cause two queries to be executed, which you may find less than ideal. This is where Roles.GetRolesForUser might be a better option:
string[] roles = Roles.GetRolesForUser(userName);
if (roles.Contains("Administrator") || roles.Contains("Manager"))
{
return RedirectToAction("Index", "AdminApp");
}
Hope that helps!
I'm using VS 2013 and it's new Identity model, I ended up going with this:
foreach (IdentityUserRole identityUserRole in user.Roles)
{
if (identityUserRole.RoleId == "AdminRoleId")
{
return RedirectToAction("Index", "Admin");
}
else if (identityUserRole.RoleId == "MemberRoleId")
{
return RedirectToAction("Index", "Members");
}
}
You need to un-nest the if statement. Revise as follows:
Change this:
FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
if (User.IsInRole("Administrator") || (User.IsInRole("Manager")))
{
return RedirectToAction("Index", "AdminApp");
}
else
{
return RedirectToAction("Index", "Home");
}
}
to this:
if (User.IsInRole("Administrator") || (User.IsInRole("Manager")))
{
return RedirectToAction("Index", "AdminApp");
}
else
{
return RedirectToAction("Index", "Home");
}
The problem is the the line if(!String.IsNullOrEmpty(returnUrl))) is evaluating to True because the returnUrl parameter has the url of the page you came from by default.

Resources