ASP.NET MVC Login Not Sticking - asp.net-mvc

I'm having an issue with my ASP.NET MVC 5 simple membership provider login code. The code is as follows:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
bool active = true;
if (ModelState.IsValid && WebSecurity.Login(model.Email, model.Password, persistCookie: model.RememberMe))
{
UserDetail userModel = UserDetail.Initialize(model.Email);
FormsAuthentication.SetAuthCookie(model.Email, true);
active = userModel.ActiveBit;
if (active)
{
return Redirect("~/");
}
else
{
WebSecurity.Logout();
ModelState.AddModelError("", "Account is inactive.");
}
}
else
{
ModelState.AddModelError("", "*Either the Username or Password provided is incorrect.");
}
return View(model);
}
The login processes successfully and I can see the authentication cookie (.ASPXAUTH) in the browser. The problem arises on the next page request. The authentication cookie is passed back to the server, but the server seems to have no record of the login any more. When I set a breakpoint and check after processing the login and requesting a new page (after completing the post-login redirect), User.Identity.IsAuthenticated is false as is WebSecurity.IsAuthenticated and WebSecurity.HasUserID. WebSecurity.CurrentUserId is -1 and WebSecurity.CurrentUserName is an empty string.
It's not a database connectivity issue since I do authenticate successfully. I do a roundtrip to the server and back and I am still not authenticated so the common answers I've seen for CurrentUser == -1 don't seem to apply.
I'm a relative newbie on MVC but I had a coworker who's got a decent amount experience on this look at my code and he couldn't find anything either. Thanks for your help.

By default asp.net MVC5 web.config not supporting FormsAuthentication, check below section of your web config file and remove "<remove name="FormsAuthentication" />" if you want to use FormsAuthentication.
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
Authentication timeout configuration
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
</system.web>
Hope this helps.

Related

MVC5 Forms authentication not working

I'm very new to .NET and security. I've chosen to implement Forms authentication (correct me if I should use something else). From what I gathered on the internet, I did the following, but it's not working:
Web.config
<authentication mode="Forms">
<forms loginUrl="~/Home/Index" timeout="30" />
</authentication>
HTTPPost ajax Login method:
[HttpPost]
public ActionResult Login(LoginInputModel loginModel)
{
if (ModelState.IsValid)
{
var success = UserService.Login(loginModel.Password, loginModel.Email);
if (success)
{
return Json(new { Url = Url.Action("Index","Home") });
}
loginModel.ErrorMessages = "Failed to log in with these credentials. Please try again.";
return PartialView("Widgets/Login/_LoginInput", loginModel);
}
return PartialView("Widgets/Login/_LoginInput", loginModel);
}
With actual login code in UserService class:
public static bool Login(string password, string email)
{
var user = Connector.GetUserByCredentials(password, email);
if (user == null) return false;
FormsAuthentication.SetAuthCookie(email, false); // this line
SessionService.Delete(UserSessionKey);
SessionService.Store(UserSessionKey, UserMapper.DbUserToUser(user));
return SessionService.HasKey(UserSessionKey);
}
Whenever I hit login, it works okay (it refreshes the page and I see different content), but if I then navigate to another page, I get redirected to the login page again. What am I (not) doing wrong?
If you need more code, I'll be happy to post it.
When you say you're using MVC5, what version of Visual Studio are you using? Are you using an application that was originally created by a default wizard?
If the application was created by the default wizard, then by default it enables ASP.NET Identity, and it removes the FormsAuthentication module from processing. If you want to keep using FormsAuth then you have to remove the "remove" key from the web.config for the FormsAuthentication module.
You need to remove this line
<system.webServer>
<modules>
<remove name="FormsAuthentication" /> <----****
</modules>
</system.webServer>

forms authentication gives a too long query string [duplicate]

This question already has an answer here:
ASP.NET MVC 5 : Endless redirect to the login page using the site template
(1 answer)
Closed 8 years ago.
Im trying to make a (temporary) login storing the users in my web.config file.
After adding deny to the web.config file it gives me this error
HTTP Error 404.15 - Not Found
The request filtering module is configured to deny a request where the query string is too long.
The url looks like this
http://localhost/Account/Login?ReturnUrl=%2FAccount%2FLogin%3FReturnUrl%3D%252FAccount%252FLogin%253FReturnUrl%253D%25252FAccount%25252FLogin%25253FReturnUrl%25253D%2525252FAccount%2525252FLogin%2525253FReturnUrl%2525253D%252525252FAccount%252525252FLogin%252525253FReturnUrl%252525253D%25252525252FAccount%25252525252FLogin%25252525253FReturnUrl%25252525253D%2525252525252FAccount%2525252525252FLogin%2525252525253FReturnUrl%2525252525253D%252525252525252FAccount%252525252525252FLogin%252525252525253FReturnUrl%252525252525253D%25252525252525252FAccount%25252525252525252FLogin%25252525252525253FReturnUrl%25252525252525253D%2525252525252525252FAccount%2525252525252525252FLogin%2525252525252525253FReturnUrl%2525252525252525253D%252525252525252525252FAccount%252525252525252525252FLogin%252525252525252525253FReturnUrl%252525252525252525253D%25252525252525252525252FAccount%25252525252525252525252FLogin%25252525252525252525253FReturnUrl%25252525252525252525253D%2525252525252525252525252FAccount%2525252525252525252525252FLogin%2525252525252525252525253FReturnUrl%2525252525252525252525253D%252525252525252525252525252FAccount%252525252525252525252525252FLogin%252525252525252525252525253FReturnUrl%252525252525252525252525253D%25252525252525252525252525252FAccount%25252525252525252525252525252FLogin%25252525252525252525252525253FReturnUrl%25252525252525252525252525253D%2525252525252525252525252525252FAccount%2525252525252525252525252525252FLogin%2525252525252525252525252525253FReturnUrl%2525252525252525252525252525253D%252525252525252525252525252525252FAccount%252525252525252525252525252525252FLogin%252525252525252525252525252525253FReturnUrl%252525252525252525252525252525253D%25252525252525252525252525252525252FAccount%25252525252525252525252525252525252FLogin%25252525252525252525252525252525253FReturnUrl%25252525252525252525252525252525253D%2525252525252525252525252525252525252FAccount%2525252525252525252525252525252525252FLogin%2525252525252525252525252525252525253FReturnUrl%2525252525252525252525252525252525253D%252525252525252525252525252525252525252FAccount%252525252525252525252525252525252525252FLogin%252525252525252525252525252525252525253FReturnUrl%252525252525252525252525252525252525253D%25252525252525252525252525252525252525252F
(without deny it sets the cookie but i can still access all the pages)
This is how it looks in my web.config
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" name=".ASPXAUTH" slidingExpiration="true" timeout="1440" path="/" defaultUrl="~/">
<credentials passwordFormat="Clear">
<user name="matchUser80" password="123Match789"/>
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
And my controller
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
if (FormsAuthentication.Authenticate(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
FormsAuthentication.RedirectFromLoginPage(model.UserName, false);
if (returnUrl != null)
{
return Redirect(returnUrl);
}
return View();
}
ModelState.AddModelError(string.Empty, "Wrong username or password");
return View(model);
}
I'm using MVC 5.
You should use attributes instead of web.config configuration to authorize your mvc application. Web config configuration should be used only with web form applications.
Decorate your Login action (both get and post version) with [AllowAnonymous] attribute.
User [Authorize] attribute for other controllers.
Read this article to see how to secure your mvc application.
Update
I reproduced your problem locally with default mvc project and i had this in my web.config:
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
</system.webServer>
Everything started working after i commented the <remove name="FormsAuthentication" /> part

View elmah logs without creating role/user authentication

I started using ELMAH and I think its great. I read some documentation online but right now my app doesn't have roles/user authorization setup.
I would like to be able to read the error logs on production by accessing /elmah.axd but I don't want to just open it up to everyone, does elmah have any functionality that would allow me to create a password (in web.config) and pass it via querystring? Mimicking a "secure" RSS feed. Or something similar ofcourse....
but right now my app doesn't have roles/user authorization setup
Actually it's not that hard to configure forms authentication:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880">
<credentials passwordFormat="Clear">
<user name="admin" password="secret" />
</credentials>
</forms>
</authentication>
and then protect elmah.axd:
<location path="elmah.axd">
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</location>
and finally you could have an AccountController:
public class AccountController : Controller
{
public ActionResult LogOn()
{
return View();
}
[HttpPost]
public ActionResult LogOn(string username, string password)
{
if (FormsAuthentication.Authenticate(username, password))
{
FormsAuthentication.SetAuthCookie(username, false);
return Redirect("~/elmah.axd");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
return View();
}
}
and a LogOn.cshtml view:
#Html.ValidationSummary(false)
#using (Html.BeginForm())
{
<div>
#Html.Label("username")
#Html.TextBox("username")
</div>
<div>
#Html.Label("password")
#Html.Password("password")
</div>
<p>
<input type="submit" value="Log On" />
</p>
}
Now when an anonymous user tries to access /elmah.axd he will be presented with the logon screen where he needs to authenticate in order to access it. The username/password combination is in web.config. I have used passwordFormat="Clear" in this example but you could also SHA1 or MD5 the password.
Of course if you don't want to configure authentication you could also configure elmah to store logging information in a XML file or SQL database and then completely disable the elmah.axd handler from your publicly facing website. Then create another ASP.NET site which only you would have access to with the same elmah configuration pointing to the same log source and simply navigate to the /elmah.axd handler of your private site to read the logs of your public site.

confused regarding forms authentication in ASP.NET MVC

Here is my config section:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="43200" cookieless="UseCookies" slidingExpiration="true" />
</authentication>
Now in the controller I have:
FormsService.SignIn(userName, true);
var temp = User.Identity.IsAuthenticated;
The temp value sometimes is set to false and sometimes to true. When the user is myself (valid and in the system). Regardless of this value in my aspx page I have:
<% if (Context.User.Identity.IsAuthenticated)
{ %>
this always resolves to true. So what am I doing wrong in my controller? And how do I check to see if the user is authenticated in the controller?
Many thanks!
You must redirect after authenticating and setting the authentication cookie. It is on the subsequent request that the user will be truly authenticated.
public ActionResult LogOn()
{
FormsService.SignIn(userName, true);
return RedirectToAction("authenticated");
}

ASP.NET MVC - Authenticate users against Active Directory, but require username and password to be inputted

I'm developing a MVC3 application that will require a user to be authenticated against an AD. I know that there is the option in MVC3 to create an Intranet Application that automatically authenticates a user against an AD, but it uses Windows Authentication and automatically logs them on. This application may be accessed on 'Open' workstations where the user will need to enter their Domain Username and Password. Any examples or online tutorial would be great. An example project would be exceptional.
You can use the standard Internet application template with forms authentication and insert an ActiveDirectoryMembershipProvider into the web.config:
<connectionStrings>
<add name="ADConnectionString" connectionString="LDAP://YOUR_AD_CONN_STRING" />
</connectionStrings>
<system.web>
<authentication mode="Forms">
<forms name=".ADAuthCookie" loginUrl="~/Account/LogOn"
timeout="15" slidingExpiration="false" protection="All" />
</authentication>
<membership defaultProvider="MY_ADMembershipProvider">
<providers>
<clear />
<add name="MY_ADMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider"
connectionStringName="ADConnectionString"
attributeMapUsername="sAMAccountName" />
</providers>
</membership>
</system.web>
In this way you get the Internet application template login form, and it validates against AD for you.
Then it's just a matter of some AccountController cleanup to remove reset password/change password/register functionality leaving just Login.
As mentioned above, you can use the membership provider defined in the web.config file.
The code below is within the implementation of the 'AccountController' from the MVC 3 Template code and has been slightly modified to work with ActiveDirectory:
[HttpPost]
public ActionResult LogOn( LogOnModel model, string returnUrl )
{
if( ModelState.IsValid )
{
// Note: ValidateUser() performs the auth check against ActiveDirectory
// but make sure to not include the Domain Name in the User Name
// and make sure you don't have the option set to use Email Usernames.
if( MembershipService.ValidateUser( model.UserName, model.Password ) )
{
// Replace next line with logic to create FormsAuthenticationTicket
// to encrypt and return in an Http Auth Cookie or Session Cookie
// depending on the 'Remember Me' option.
//FormsService.SignIn( model.UserName, model.RememberMe );
// Fix this to also check for other combinations/possibilities
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
If using .NET 3.5 -- then read this article for the alternative:

Resources