ASP.NET MVC4 Simplemembership or autoFormsAuthentication? - c#

I'm new to ASP.NET MVC4 and therefore read many things about how to authenticate on an Intranet Website.
I've inherited of this type of project in order to improve it and after quick reading the source code, I saw that login/password are stored in clear text in a SqlServer database...
So my first improvement is to upgrade the authentication process in order to store passwords in the right manner.
Here is what I've done so far, in my GlobalAsax.cs add :
WebSecurity.InitializeDatabaseConnection(
connectionStringName: "AppConnectionString",
userTableName: "Employe",
userIdColumn: "IDE",
userNameColumn: "E_mail",
autoCreateTables: true);
in order to add the "webpages_*" tables to my database.
I changed the IIS configuration in order to deactive "AllowAnonymous" connection and activate "Basic Authentication".
But now I'm faced to Forms vs SimpleMembership, my Web.config:
<add key="autoFormsAuthentication" value="false" />
<add key="enableSimpleMembership" value="true" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="30" />
</authentication>
Can someone explain me clearly the use of each attribute?
I don't understand because autoFormsAuthentication is set to false but authentication use it after.
What the enableSimpleMembership?
Thanks

It's hard to find any information on the topic but in my opinion autoFormsAuthentication set to true will set:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
If you need other parameter you need to use <authentication mode="Forms">
explicity.
Also autoFormsAuthentication redirecting unauthorized users from any contollers. Not only with 'authorize' attribute.
But it is just my opinion...

Related

Receiving a 500 error when configuring an ASP.NET login page

I want to add a login page to an ASP.NET Framework site, but the compiler doesn’t even load the view, instead throwing an error on the configuration.
The web.config contains the following configuration:
<authentication mode="Forms">
<forms loginUrl="/Login/Login"></forms>
</authentication>
My LoginController contains the following:
public class LoginController : Controller
{
[HttpGet]
public ActionResult Login()
{
return View();
}
}
But this is the error I receive:
The configuration section 'authentication' cannot be read because it is missing a section declaration
The <authentication/> element was first introduced in ASP.NET 2.0 as part of Forms-Based Authentication, which appears to be what you’re trying to configure.
If so, it is expected under the <system.web /> element (source):
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="/Login/Login"></forms>
</authentication>
</system.web>
</configuration>
You don’t provide the full context for your web.config file, but according to the screenshot of the error message, it appears as though you’ve inadvertently placed your <authentication /> element as a sibling of the <system.web /> element, not as a child.
The error message here certainly isn’t intuitive. But placing the <authentication /> element under the system.web element should resolve your issue.
Note: Since Internet Information Server (IIS) 7, there is also an <authentication /> element located under the <system.webServer /> element, under <security/> (source). This is a used to configure IIS’s authentication, and is independent of the ASP.NET Framework’s Form-Based Authentication.

Forms Authentication works locally, but not on dev server

I know Forms Authentication is old, but when I run the web application locally using IIS Express, everything works well. But when I publish it to our development/test server, it just reloads the page. The dev server is running IIS 6.
One more thing to note, locally it runs as localhost:50264/Login. On the dev server, the url is more like http://dev1.server.com/op/webapp/Account/Login.
I notice that both of the cookies have the path "/". I did try to set change that by having this in my local web.config:
<add key="CookiePath" value="/" />
And then when I publish to our dev server it changest to:
<add key="CookiePath" value="http://dev1.server.com/op/webapp/" xdt:Transform="Replace" xdt:Locator="Match(key)" />
That didn't seem to work.
In another thread that I found in Stack Overflow, someone suggested to add this to the :
<system.webServer>
<modules>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
</modules>
</system.webServer>
That didn't work either. Any help would be greatly appreciated!
UPDATE: 9/29/2016
I removed the CookiePath app setting and, instead made an adjustment to the authentication node. In my Web.config I now have:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" requireSSL="false" slidingExpiration="true" path="/" />
</authentication>
And in my Web.Debug.config I have:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" requireSSL="false" slidingExpiration="true" path="/op" xdt:Transform="Replace" />
</authentication>
Finally, when I create the cookie:
var authTicket = new FormsAuthenticationTicket(
1,
user.Email,
DateTime.Now,
DateTime.Now.AddDays(14),
true,
userData,
FormsAuthentication.FormsCookiePath);
When I deploy to the dev server, I check the web.config there and it did transform the forms node correctly.
When I go to login, I enter my credentials and it still refreshes the Login page. With the Chrome extension "EditThisCookie" I still see that the path of the cookie is "/". It doesn't recognize the change AT ALL. Even when I manually set the path of authTicket path to "/op" the cookie STILL has the path as "/". I have no idea what's going on. Ugh...
I use forms authentication also, here's my settings. You didn't show all your forms Authentication code, but hopefully this will point you in the right direction.
Web.Config
<authentication mode="Forms">
<forms loginUrl="members/login.aspx" name=".ASPXFORMSAUTH" requireSSL="false" slidingExpiration="true" timeout="120" />
</authentication>
Then I set the cookie in the code behind when the user logs in.
Dim authCookie As HttpCookie = FormsAuthentication.GetAuthCookie(iMembersID, False)
Dim ticket As FormsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value)
Dim newTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, "Member")
authCookie.Value = FormsAuthentication.Encrypt(newTicket)
Response.Cookies.Add(authCookie)
Then I test to see if they are authenticated on all pages that require the user to be logged in.
If Request.IsAuthenticated Then
Dim ident As FormsIdentity = CType(User.Identity, FormsIdentity)
If ident IsNot Nothing Then
Dim ticket As FormsAuthenticationTicket = ident.Ticket
Dim userDataString As String = ticket.UserData
Select Case ticket.UserData
Case "Member"
m_MemberLoggedIn = ident.Name
Case Else
Response.Redirect("~/members/login/", True)
End Select
Else
Response.Redirect("~/members/login/", True)
End If
Update 9/29:
Check to make sure the IIS Authentication mode to set to Anonymous
I went the easy way out and asked our IT Dept to create a subdomain so the path of the cookie will always be "/". Not an answer, but it's what I did.

Getting Authentication Form Timeout

I'm using the following code in Global.asax.cs (which I believe is an MVC conventional name)
Configuration conn = WebConfigurationManager.OpenWebConfiguration("");
AuthenticationSection section = (AuthenticationSection)conn.SectionGroups.Get("system.web").Sections.Get("authentication");
Application["Expire"] = System.Convert.ToInt64(section.Forms.Timeout.TotalMinutes);
to grab the timeout from the following form in Web.Config
<authentication mode="Forms">
<forms name=".FooAuth" path="/" protection="All" requireSSL="false" loginUrl="~/Member/Login" timeout="30" />
</authentication>
Application["Expire"] always gets 30, despite any changes to the timeout variable. I'm thinking that I must be changing the wrong variable somewhere. Thanks in advance for the help!

Configuring custom authorization with ELMAH

How can I configure ELMAH to display only for certain people without default ASP.NET authorization roles manager?
I (as well as many others, I think) use my own authorization logic and build my projects from zero without using provided templates. I want to log errors but it seems that it is impossible to configure ELMAH (somehow override functionality) to make it work with some other authorization or even to make it work only for particular IP addresses.
Since I will have access to web.config I tried to change these values in order to NOT display elmah by default.
<add key="elmah.mvc.disableHandler" value="false" />
<add key="elmah.mvc.disableHandleErrorFilter" value="false" />
<add key="elmah.mvc.requiresAuthentication" value="false" />
And when I want to view errors switch them from true to false and see errors, then switch back. But it seems that when I change these values all logs are erased.
What can I do?
I think the easiest approach would be to make some minor alterations to your custom authorization so the ELMAH authorization will work.
Option 1: Set the FormsAuthentication cookie on login. This way, in the web.config the allow users="username" should work. On successful login you can set the cookie with
FormsAuthentication.SetAuthCookie(theUsername, true).
The ELMAH authorization would look something like:
<location path="elmah.axd" inheritInChildApplications="false">
<system.web>
<authorization>
<allow users="theUserName" />
<deny users="*" />
</authorization>
</system.web>
...other config settings
</location>
Option 2: If you are using putting users into roles, you can override the default role provider to use the function you made to get roles. This way is a little more involved but then lets you harness role-basing authentication in the web.config, which is really nice for securing things like static file (.pdf etc) delivery. I can add code for this if interested.
I was using the ASP.NET Identity Framework, so this answer is regarding that setup. I also used the Elmah.MVC package in NuGet. I edited the following lines in web.config. (you need to supply your own user name in the allowedUser setting)
<add key="elmah.mvc.requiresAuthentication" value="true" />
<add key="elmah.mvc.allowedRoles" value="*" />
<add key="elmah.mvc.allowedUsers" value="your_user_name" />
It appears that ELMAH does get the authentication information from the current thread principal, which the ASP.NET Identity Framework will establish on your behalf upon login.
It doesn't matter how the system gets the username or roles in this case. Whether it be from the built-in providers, a provider you implement yourself, or if during your custom authentication you populate this information yourself. All it takes is to manually set the principal during something like the Application_PostAuthenticationRequest event. This should give you the jist of it.
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
//Obtain username and roles from application datastore and use them in the next line
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("userNameHere"),
new string[] { "Admin", "CanDeleteStuff", "CanEditStuff", "OtherRole" }
);
}
This will let you use something like this in your web.config
<location path="elmah.axd" inheritInChildApplications="false">
<system.web>
<authorization>
<allow roles="Elmah"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
Not to mention being able to use User.IsInRole("CanEditStuff") in your code.

Dual forms authentication in asp.net 2.0 - 4.0

BACKGROUND
I have two websites under the same domain. One website encapsulates Login/Account Management functions only and the other website is the real website.
LoginWeb - only Login Page/css/images/javascript folder allow anonymous access
AdminWebsite - completely locked down via forms auth. i.e not even javascript/images/css folders have <authorization><allow users=*>
WHAT I AM TRYING TO ACHIEVE
This is the workflow I am trying to achieve and have accomplished 99% of it :
If the user hits any page on AdminWebsite he is sent back to LoginWeb by FormsAuthentication
User supplies credentials in the loginpage and LoginWeb website issues a forms auth ticket. User is still not logged into AdminWebSite yet. (This way user can go to changepassword page etc and do account management functions)
User goes to two more steps in LoginWeb and now can be issued the FormsAuth ticket for AdminWebsite and redirected to it.
99% IS ALREADY WORKING
This is the code in LoginWeb which tries to issue the FormsAuth ticket for AdminWeb, but it is not working. i.e AdminWeb is still redirecting me back to Login. I am sure there is something very trivial I am missing but I can't figure out what exactly it is?????????
public void SetAuthenticationTicket(string username)
{
MachineKeySection sec=(MachineKeySection)WebConfigurationManager.OpenWebConfiguration("").SectionGroups["system.web"].Sections["machineKey"];
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
username,
DateTime.Now,
DateTime.Now.AddMinutes(30),
false, //true or false
sec.DecryptionKey, //Custom data like your webkey can go here
FormsAuthentication.FormsCookiePath);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie("ADMINWEB", encryptedTicket)
{
Path = FormsAuthentication.FormsCookiePath,
Domain = "xxx.com"
};
Response.AppendCookie(cookie);
}
These are my web.config sections for Forms Auth:
LoginWeb
<machineKey validationKey="XXXXXX" decryptionKey="XXX" validation="SHA1"/>
<authentication mode="Forms">
<forms name="LoginWeb"
domain="xxx.com"
loginUrl="~/account/Logon"
timeout="1440"
cookieless="UseCookies"
slidingExpiration="false"
protection="All"
path="/"/>
</authentication>
AdminWebSite
<machineKey validationKey="XXXXXX" decryptionKey="XXX" validation="SHA1"/>
<authentication mode="Forms">
<forms name="ADMINWEB"
domain="xxx.com"
loginUrl="http://loginweb/account/Logon"
timeout="1440"
cookieless="UseCookies"
slidingExpiration="false"
protection="All"
path="/"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
This site, Forms Authentication Across Applications, implies that the Name on the forms attribute should be the same.

Categories