Multiple membership providers in ASP.NET (web.config + sql) - asp.net

I know this question is asked (and answered) a lot already, but I believe my situation is unique.
We are using the ASP.NET SqlMembershipProvider. However, we also have some less-secure content we would like to secure by adding users directly to the web.config, like so...
<forms loginUrl="login.aspx" defaultUrl="default.aspx">
<credentials passwordFormat="Clear">
<user name="user1" password="123" />
<user name="user2" password="456" />
</credentials>
</forms>
Is it possible to use this method alongside a SQL Membership Provider? If so, how?
I know it's bad practice to do this. This is only a stepping stone as we move parts of our website into the asp.net application. We would like some of those password to be easily editable without going to the database.

We would like some of those password
to be easily editable without going to
the database.
What is that logic I don't understand. Why you need two of them while you have built-in feature to change password easily in membership provider.
Now, you can use both at a time but you will need mechanism to decide when you use what or you will have to to two times authentication i.e. first validate user against web.config and if it fails then validate against membership DB.
But if you have other stuff depending on Membership explicitly, then some of those things won't work on your site.
So authentication, yes it is doable as you want.

I found my answer here: ASP.NET - Login Control with Credentials in web.config file
For my ValidateUser logic, I needed to use:
if (_provider.ValidateUser(username, password)) {
return true;
}
else {
return FormsAuthentication.Authenticate(username, password);
}
I knew how to authenticate using a provider, but the key was the ELSE clause, and authenticating using the web.config credentials.

Related

Authentication cookie not working after aplication pool reloads

I use Form Based Authentication in my site
In my login page I have:
FormsAuthentication.SetAuthCookie(user.userName, true)
When I want to check if the user is authenticated I do:
HttpContext.Current.User.Identity.IsAuthenticated
I'm not using Asp.net Membership, instead i use my on SQL-DB verification
do i have to use Asp.net Membership ?
This is working for me most of the times
The problem is that sometimes after 5 hours or something after 30 hours
The Application pool gets restarted for some reason (I’m on a shared server)
And after that the “User.Identity.IsAuthenticated” returns with false, every time until the user logs in again.
This is strange to me because I can see that the client still have the persistent authCookie so why the user is not authenticated ?
My Web.Config reference:
<authentication mode="Forms">
<forms
name="AuthCookie"
loginUrl="~/mySite/ManageLogin.aspx"
timeout="5256000"/>
</authentication>
Any help will be appreciated.
My site www.mentallica.co.il
This may be due to the automatic generation of the machinekey at the application start. You can prevent that by specifying a machinekey for your app in your web.config:
<machineKey
validationKey="410E4E2B06BE457709F2D8C72BB02957A3B4E8BA327F3A6103696857AD3A88598D454489B9D4CAAFC2D5E35E8795B311EE2E94DAA485FD64D7184272A4AE4D8B"
decryptionKey="EFAFA0917D0D8F137F05B26AE053397C48D34DE688E73483D15C8EDAF0D6FD4F"
validation="SHA1"
decryption="AES" />
You shouldn't use this one - you may create your own easily at http://aspnetresources.com/tools/machineKey .
More information about machinekeys: http://msdn.microsoft.com/en-us/library/ff649308.aspx

Role-based Security without Forms Authentication in ASP .NET

I would like to take advantage of:
Page.User.IsInRole("CustomRole");
Page.User.Identity.IsAuthenticated
when working inside Page methods, as well as authorization section in web.config:
<authorization>
<allow roles="Administrators, Supervisors" />
<deny users="*" />
</authorization>
and also apply rules on classes and methods level:
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
In my application I authenticate with ... custom mechanism that provides me user identity in ... http header. I get users PIN number (some kind of ID) + roles. But that is a side plot. It doesn't matter.
What I actually want to achieve is to take advantage of ASP .NET build in Authorization features but having my custom authentication mechanism. I guess I have to implement IPrincipal and IIdentity, is that right? I saw plenty of samples on the web but all of them include web.config configuration that specifies providers, and also FormsAuthentication like classes, that I guess I don't need. I just need to inject my user object (which is prepared by me) into request and that's it.
So:
what's the easiest way to achieve it?
what is the difference between GenericPrincipal / IPrincipal?
how to get/create IIdentity object? I saw samples with:
var id = new FormsIdentity(authTicket);
but I'm not using FormsAuthentication.
Thanks
In short, you have to implement your own authentication module.
An authentication module is just an ASP.NET module but having special purpose. Its AuthenticateRequest method should populate HttpContext.Current.User property with an instance of IPrincipal.
Answering your other questions: IPrincipal is just an interface while GenericPrincipal is one of its implementations. You can use it, as the name suggests it's just a generic implementation which means that it should suit you. Since IPrincipal is just IIdentity plus roles, you probably will also need GenericIdentity.
Other implementations, like RolePrincipal + FormsIdentity are designed for specific purposes, these two for example are used by the Forms Authentication Module.
There are some good examples available, just google for "custom authentication module".
Before you do (create/implement your own), have you tried/considered adapting Forms Authentication to your existing auth scheme?
I think you're "almost there" (using all of the built-in ASP.net auth/membership/profiles/roles), and it maybe easier/simpler to just "plug in" your existing auth scheme into Forms Authentication.
This snippet of code should give you an idea of how flexible Forms Authentication can be:
if ((UserEmail.Text == "jchen#contoso.com") && (UserPass.Text == "37Yj*99Ps"))
{
FormsAuthentication.RedirectFromLoginPage
(UserEmail.Text, Persist.Checked);
}
else
{ ... }
So, it works with a hard coded "auth scheme" (not that you should, but gives you an idea of the possibilities), or even a list in web.config - again, just a sample:
<authentication mode="Forms">
<forms name=".FUBAR">
<credentials passwordFormat="MD5">
<user name="foo" password="b7ab5072e8fba7bed20384cc42e96193"/>
<user name="bar" password="1c42e49a360aa7cc337a268a1446a062"/>
<user name="john" password="5f4dcc3b5aa765d61d8327deb882cf99"/>
<user name="jane" password="7c6a180b36896a0a8c02787eeafb0e4c"/>
</credentials>
</forms>
</authentication>
Just a thought - hth....

custom authorization - roles done, what about users?

I'm moving from an integrated/windows authenticated system (whereby I used windows groups in the web.config's authorization section, and the web.sitemap as well as using user.identity.name for various per-user features) to an SSO solution which offers authenticated details through the http headers.
I created a very simple custom RoleProvider (overriding IsUserInRole and GetRolesForUser) which worked great for the 'allow roles' sections of the web.config, and roles section of web.sitemap.
I want to do the same for the 'users' part of authorization.. how would I go about doing this? Is it through overriding a different provider? Would it also affect what's returned by user.identity.name?
Thanks for pointing me in the right direction :)
Edit - for Jay.
Note this is likely a bit of a hacky and inexperienced fix, but it suited my purpose.. Following http://msdn.microsoft.com/en-us/library/8fw7xh74(v=vs.100).aspx you can create a class with all the required function definitions, returning false/empty string arrays as necessary.
The only functions I implemented were IsUserInRole and GetRolesForUser. The latter simply hooked into Request.ServerVariables to check the appropriate HTTP header, and format those into a String array as required. The IsUserInRole simply matches a supplied string against the string array returned by GetRolesForUser.
After that, I just referenced the above in the web.config
<roleManager defaultProvider="myroleprov" enabled="true">
<providers>
<clear/>
<add name="myroleprov" type="myApp.CustomProviders.myroleprov" applicationName="myApp"/>
</providers>
</roleManager>
I think that's about it? Hope it helps.
I think you're looking for the Membership provider: http://msdn.microsoft.com/en-us/library/system.web.security.membershipprovider.aspx

Using Forms Authentication without .Net providers

I want to protect a section of my website using forms authentication with the username and password as defined by me in the web.config. When I attempt to login I get the message below.
Server Error in '/' Application.
Could not find stored procedure 'dbo.aspnet_CheckSchemaVersion'.
I'm guessing this is happening because it's attempting to use the Membership tables as defined by the LocalSqlServer connection string. I don't want to use the Membership features, how do I configure my web app to do that?
Will I need to write the Authenticate function myself for the in-built Login control?
The problem isn't with your config file, it's with the Login control.
The Login control uses the default Membership Provider that is defined in the machine.config. (It's a SqlMembershipProvider that points to a SQL Express database).
You don't want to use the default Membership Provider at all. Simply create your own login page and use the following server-side logic to validate the credentials and log the user into the site:
if( Page.IsValid )
if (FormsAuthentication.Authenticate(txtName.Text,txtPassword.Text))
FormsAuthentication.RedirectFromLoginPage(txtName.Text, false);
else
lblMsg1.Text = "Wrong name or password. Please try again.";
Try this:
<authentication mode="Forms">
<forms loginUrl="Login.aspx">
<credentials>
<user name="Joe" password="Smith" />
</credentials>
</forms>
</authentication>

How do I logout of multiple asp.net applications?

I have a main asp.net app, which is written in asp.net 1.1. Runnning underneath the application are several 2.0 apps. To completely logout a user can I just logout of the 1.1 app with FormsAuthentication.SignOut or is it more complicated than that?
What you are looking to do is called Single Sign On and Single Sign Off. There are differences based on how you have the applications set up. I will try to clarify where those differences come into play.
To implement single sign on and single sign off you need to make the cookie name, protection, and path attributes the same between all the applications.
<authentication mode="Forms">
<forms name=".cookiename"
loginUrl="~/Login.aspx"
timeout="30"
path="/" />
</authentication>
Next you need to add the machine keys and they need to be the same between all your applications.
<machineKey validationKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902"
encryptionKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC"
validation="SHA1" />
Are you using second or third level domains for the applications? If so you will need to do a little bit more by adding the domain to the cookie:
protected void Login(string userName, string password)
{
System.Web.HttpCookie cookie = FormsAuthentication.GetAuthCookie(userName, False);
cookie.Domain = "domain1.com";
cookie.Expires = DateTime.Now.AddDays(30);
Response.AppendCookie(cookie);
}
Now to do single sign off, calling FormsAuthentication.SignOut may not be enough. The next best thing is to set the cookie expiration to a past date. This will ensure that the cookie will not be used again for authentication.
protected void Logout(string userName)
{
System.Web.HttpCookie cookie = FormsAuthentication.GetAuthCookie(userName, False);
cookie.Domain = "domain1.com";
cookie.Expires = DateTime.Now.AddDays(-1);
Response.AppendCookie(cookie);
}
I am taking into consideration you are using the same database for all the applications. If the applications use a separate database for registration and authentication, then we will need to do some more. Just let me know if this is the case. Otherwise this should work for you.
It could be easier if you are having a central session store for all your applications. You can then set the session to null in one place.
This worked for me:
In the Logout event, instead of FormsAuthentication.GetAuthCookie method use Cookies collection in Request object as below:
HttpCookie cookie = Request.Cookies.Get(otherSiteCookieName);
cookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
Ofcourse, this requires u know the Cookie name of the site(s) you want the user to be logged out - which however won't be a problem if you are using the same cookie across all the web apps.
I prefer to use web.config
<authentication mode="Forms">
<forms domain=".tv.loc" loginUrl="~/signin" timeout="2880" name="auth" />
</authentication>

Resources