ASP .NET MVC3 application uses login controller from MVC3 application template below. Controllers are decorated by [Authorize] attribute:
[Authorize]
public class CheckoutController : ControllerBase
User enters user name and password and click "remember me" checkbox. Authorization cookie is stored in browser and credentials are no more asked on subsequent accesses.
User can disabled by setting disabled fields in accounts database.
If such user tries to log on membership provider returns error and login fails.
However if user is already logged in, membership provider is not called. Disabled user can continue to use application.
How to fix this so that disabled user cannot use application ?
LogOn controller is basically from Visual Studio MVC3 sample application template:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (string.IsNullOrWhiteSpace(model.UserName) || string.IsNullOrWhiteSpace(model.Password))
{
ModelState.AddModelError("", "User or password not filled");
return View(model);
}
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Logon error");
}
return View(model);
}
Related
I am working on an asp.net MVC4 web application, and for the login i am using form authentication that is connected to our AD using LDAP connection string, as follow.
The login Get action method:-
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
returnUrl = TempData["returnUrl"] != null ? TempData["returnUrl"].ToString() : String.Empty;
List<String> domains = new List<String>();
domains.Add("*****");
ViewBag.ReturnUrl = returnUrl;
ViewBag.Domains = domains;
return View();
}
The Login Post action method:-
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
MembershipProvider domainProvider;
domainProvider = Membership.Providers["TestDomain1ADMembershipProvider"];
if (ModelState.IsValid)
{
// Validate the user with the membership system.
if (domainProvider.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
List<String> domains2 = new List<String>();
domains2.Add("****");
ViewBag.Domains = domains2;
return View(model);
}
return RedirectToLocal(returnUrl);
}
List<String> domains = new List<String>();
domains.Add("****");
ViewBag.Domains = domains;
return View(model);
}
Now i have been using this system for 5 years and never face any issue with user login. but today a new user mentioned that when he tried to login to the system he will get an error "Error while processing your request.", and this error will be raised in our system if an unhandled exception is being raised. and i checked the IIS log and i can see that the user did not access the system.
so the only issue i can think of is that the user's password contain characters which MVC does not allow. for example i tried to type this password <script>#1234 along with my username, and instead of getting this message "The user name or password provided is incorrect." , i got the same exception "Error while processing your request.".. of course i can not ask the user to mention his password, but i am not sure how i can allow MVC to accept any password passed to it? as i can not think of any other problem...because usually when users login to the application they either; login successfully Or get "The user name or password provided is incorrect." , but i never face a problem where the user get an exception... which i were able to replicate by passing unsafe characters <script>#1234
In your LoginModel make add the AllowHtmlAttribute to the Password field. This will bypass the check against input like <script>.
[AllowHtml]
public string Password { get; set; }
Use it sparing, of course. MVC is trying to protect you from script injection attacks, so you should only disable this check in a few cases where you can be sure the value is handled safely. (In this case, passwords should never be displayed to the user, so even if there is HTML in it, it cannot inject HTML onto the page).
Alternatively, if you cannot alter the LoginModel class, you could try adding the ValidateInputAttribute to your Login POST method.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Login(LoginModel model, string returnUrl)
Hi guys I'm working on a project in which we can disable our users. There is a column name status in user table that can be true or false. Now I want to add a new rule in default asp.net user login that if a user is disable(his column name status equals false), should not able to login with an error message that "Admin have disabled your account".
I have looked in,
ManageController.cs
IdentityConfig.cs
ManageViewModles.cs
IdentityModel.cs
but I didn't get any clue. How can I add this rule in my asp.net MVC-5 application
You could define a verification with an async function in your login view controller and call it on Login button press.
Good place to start: here
EDIT
Here some code sample you could have in your HomeController->Index Action. Note that this isn't async but you could implement an async action with your db call:
[HttpGet]
public ActionResult Index()
{
//Verification of user
//if true
return View();
//else false
return ErrorView(); //View that contains the error message
}
In login method of account controller i achieved it using this code.
I updated code in my switch(result) of case SignInStatus.Success:
case SignInStatus.Success:
var userID = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.GetUserId();
AspNetUser res = db.AspNetUsers.Where(x => x.Id == userID).Select(x => x).FirstOrDefault();
if (res.Status == "False")
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
// return RedirectToAction("Index", "Home");
ModelState.AddModelError("", "Admin has disabled your account.");
return View(model);
}
//remaining code here
In my application, all my authentication happens with Google - ie - all my users are Google Accounts.
I don't need users to need to register in my app, just sign in using a Google account. However, I do want to manage Roles for the users with ASP.net Identity (I think)
With that in mind, on successful external authentication, I create an ASP.net Identity user (if one doesn't exist)
So, I've got my ExternalLoginCallback as follows:
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var authenticationManager = Request.GetOwinContext().Authentication;
var loginInfo = await authenticationManager.GetExternalLoginInfoAsync();
//successfully authenticated with google, so sign them in to our app
var id = new ClaimsIdentity(loginInfo.ExternalIdentity.Claims, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(id);
//Now we need to see if the user exists in our database
var user = UserManager.FindByName(loginInfo.Email);
if (user == null)
{
//user doesn't exist, so the user needs to be created
user = new ApplicationUser { UserName = loginInfo.Email, Email = loginInfo.Email };
await UserManager.CreateAsync(user);
//add the google login to the newly created user
await UserManager.AddLoginAsync(user.Id, loginInfo.Login);
}
return RedirectToLocal(returnUrl);
}
Idea being, I can now manage users, add roles, check if users are in roles, etc....
Firstly, is this a sensible approach? Or have I over complicated it?
One issue I'm having, however, is with logging out of my application
My Logout action looks like:
public ActionResult LogOut()
{
HttpContext.GetOwinContext().Authentication.SignOut();
return RedirectToAction("Index", "Home");
}
My Index action is decorated with the [Authorize] attribute -
However, when I 'logout' - it redirects to Home.Index - but I still seem to be logged in?
According to this ASPNet Identity Work Item, this is by design, and you need to call directly to Google's API in order to log the user out.
completing the post Logout link with return URL (OAuth)
Here is a solution that work for me :
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return Redirect("https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=https://[url-of-your-site]");
}
I am having issues understanding what I need to do with this and how to get them to interact.
I have created an MVC 4 Internet Application. From what I understand, the login mechanism uses the SimpleMembershipProvider which is not compatible with the SQL based ASP.NET Membership provider.
I have an existing site that uses ASP.NET Membership and we are going to be leveraging this. I only need a login controller. The User name is being passed in by the original application that is calls my new application. This is all on an intranet, and we are creating a simple SSO model.
From what I can tell I will need to add in the "DefaultMembershipProvider" entry into the web.config and create a connection string to my membership DB. I have that much.
But I am unclear as to what the code will need to look like for the controller.
Here is the code that I currently have for the controller for the simple provider:
[HttpPost]
[AllowAnonymous]
public ActionResult LoginAuto(string userid)
{
LoginModel model = new LoginModel();
if (!string.IsNullOrEmpty(userid))
{
model.UserName = userid;
model.RememberMe = true;
model.Password = "Dude!!!!1";
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return RedirectToAction("Index", "Home");
}
}
else
{
model.UserName = "";
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View("Login", model);
}
Will I need to change this at all? Will the actual controller class be different from what comes with the template? I'm pretty new to the actual security thing and looking for some direction.
Thanks.
I'm trying to build a two-step custom registration for users in my ASP.NET MVC 4 application. This involves redirecting users after registration to the Edit view in the User Controller. I've tweaked the code in the stock Account Controller template to achieve this.
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Edit", "User", new { id = WebSecurity.CurrentUserId });
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
return View(model);
}
However when I run this I get a 404 on the address bar it shows
http://localhost:17005/User/Edit/-1
Which means it's going into the Edit action of user controller, but then ending up with a Id of -1. Any help would be appreciated.
Membership.GetUser().ProviderUserKey
Alternatively you could not pass a user id to the edit action and have the code use the currently logged in user.
RedirectToAction("Edit", "User");
In your user controller
[Authorize]
public ActionResult Edit()
{
object userId = Membership.GetUser().ProviderUserKey;
}
Please excuse brevity as I am currently on my mobile