ASP.NET 2.0 Security Questions and Answers - Authentication

From Guidance Share

Jump to: navigation, search


Contents

What's new in ASP.NET 2.0 in terms of Authentication?

ASP.NET version 2.0 introduces a membership feature, which provides a consistent API for user credential storage and management. You can use membership with forms authentication.


Membership supports a provider model, with the SqlMembershipProvider for SQL Server databases and ActiveDirectoryMembershipProvider for Active Directory and Active Directory Application Mode (ADAM) stores provided as built-in providers. The provider model is extensible and you can create custom providers for your custom user stores.


ASP.NET version 2.0 also provides built in Login controls including Login, LoginView, LoginName, CreateUserWizard, and ChangePassword controls which work with the membership feature.


If you don't want to use the login controls or have existing code that you want to migrate to using membership, you can use membership APIs like CreateUser, and ValidateUser for manual user management and authentication.


More Information

For more information on using the membership feature, see “How To: Use Membership in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000022.asp


How do I decide my Authentication strategy in ASP.NET?

Use Windows authentication wherever you can because it provides secure credential management, password policies, and user account management tools. If your application users have Windows accounts, but you cannot use Windows authentication because of firewall issues, use forms authentication with the ActiveDirectoryMembershipProvider. If your user accounts are held in a SQL Server database, use forms authentication with the SqlMembershipProvider. If your user accounts are in an Application Directory Application Mode (ADAM) store, use forms authentication with the ActiveDirectoryMembershipProvider. If your user accounts are in a store other than the previously listed stores, create a custom membership provider and configure forms authentication to use it.


How do I use Forms Authentication with SQL Server database?

Use the built-in SqlMembershipProvider along with the Login control.


Membership provides a consistent and simple APIs for user authentication and user management and the Login control works with membership. The control coupled with the membership provider significantly reduces the amount of code you need to write to authenticate your users.


To use forms authentication with a SQL Server database as the user store:

  • Install the SQL Server user store database by using the aspnet_regsql.exe utility.
  • From a Visual Studio 2005 command prompt, run the following command.
    aspnet_regsql -S (local) -E -A m
    
    • -S specifies the server, which is (local) in this example.
    • -E specifies to use Windows authentication to connect to SQL Server.
    • -A m specifies to add only the membership feature. For simple authentication against a SQL Server user store, only the membership feature is required.
  • Create a SQL Server login for your ASP.NET application's process identity (or impersonated identity if your application uses impersonation) and grant it the appropriate permissions in the membership database.
  • Configure your application for Forms authentication in the Web.Config file as follows
    <authentication mode="Forms">
  • Configure your application to deny access to unauthenticated users in Web.config file as follows
    <authorization> 
       <deny users="?" />
    </authorization>
    
  • Configure a database connection string in the connectionStrings section to point to the membership database in SQL Server as follows:
    <connectionStrings>
      <add name="MyLocalSQLServer"
                  connectionString="Initial Catalog=aspnetdb;
              data source=localhost;Integrated Security=SSPI;" />
    </connectionStrings>
    
  • Configure the SqlMembershipProvider, using the connection string. Ensure that the defaultProvider attribute is set to the configured provider as follows:
    <membership defaultProvider="MySqlMembershipProvider" >
        <providers>
           <clear/>
               <add name="MySqlMembershipProvider"
                    connectionStringName="MyLocalSQLServer"
                    applicationName="MyAppName"
                    type="System.Web.Security.SqlMembershipProvider, 
                    System.Web, Version=2.0.0.0, Culture=neutral, 
                    PublicKeyToken=b03f5f7f11d50a3a" />
        </providers>
    </membership>
    
  • Configure password complexity rules if you need to override the defaults, which ensure a minimum length of 7 characters with one of them being non-alphanumeric.
  • Use the Login and CreateUserWizard controls to create a login page (Login.aspx) for forms authentication.
  • Encrypt the connectionStrings configuration section by using protected configuration.


More Information

For information on forms authentication using SQL Server database, see “How To: Use Forms Authentication with SQL Server in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000014.asp


How do I use Forms Authentication with Active Directory?

Use the built-in ActiveDirectoryMembershipProvider. Use the new login controls to create a forms authentication login page.


To use forms authentication with an Active Directory user store:

  • Configure your application for Forms Authentication in the Web.Config file as follows
    <authentication mode="Forms">
    
  • Configure your application to deny access to unauthenticated users in the Web.config file as follows:
    <authorization> 
       <deny users="?"/>
    </authorization>
    
  • Configure an LDAP connection string in the connectionStrings section of Web.config to point to the Active Directory to be used.
    <connectionStrings>
       <add name="ADConnectionString" 				   
          connectionString="LDAP://testdomain.test.com/CN=Users,
          DC=testdomain,DC=test,DC=com" />
    </connectionStrings> 
    
  • Configure the ActiveDirectoryMembershipProvider in the Web.config file specifying at least the connection string name and optionally the credentials (using connectionUserName and connectionPassword attributes) of an account with permissions to access Active Directory. If you do not specify account credentials, your application's process identity is used to access Active Directory, regardless of whether your application uses impersonation.
  • Ensure that the defaultProvider attribute is set to the provider configured.
    <membership defaultProvider="MyADMembershipProvider">
       <providers>
          <add
             name="MyADMembershipProvider"
             type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, 
                   Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="ADConnectionString"
             connectionUsername="testdomain\administrator" 
             connectionPassword="password"/>
       </providers>
    </membership>
    
  • Use the Login control to create a login page (login.aspx) for forms authentication.
  • Encrypt the connectionStrings section using protected configuration. Also if you specify user credentials in the ActiveDirectoryMembershipProvider configuration encrypt the membership configuration section as well.


More Information

For information on forms authentication using Active Directory, see “How To: Use Forms Authentication with Active Directory in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000026.asp


How do I enable Forms Authentication to work with multiple Active Directory domains?

Configure ActiveDirectoryMembershipProvider for each domain. Create a custom login form using a TextBox server control to obtain user credentials and domain information. Depending upon the domain information, use the domain specific ActiveDirectoryMembershipProvider instance for manually authenticating the user.


Note that membership by default works with a single domain only (configured as the defaultProvider). Also you cannot use the login controls in a multiple domain scenario, because they work with only the configured default membership provider. So you need to create a custom login form using TextBox server controls.


To use forms authentication with multiple domains

  • Configure your application for Forms Authentication in the Web.config file as follows
    <authentication mode="Forms">
    
  • Configure your application to deny access to unauthenticated users in the Web.config file as follows
    <authorization> 
       <deny users="?"/>
    </authorization>
    
  • Configure multiple connections strings for multiple domains in the Web.config file as shown here.
    <connectionStrings>
       <add name="TestDomain1ConnectionString" 
            connectionString="LDAP://testdomain1.test.com/CN=Users,
                              DC=testdomain1,DC=test,DC=com" />
       <add name="TestDomain2ConnectionString"  
            connectionString="LDAP://testdomain2.test.com/CN=Users,
                              DC=testdomain2,DC=test,DC=com" />
       <add name="TestDomain3ConnectionString" 
            connectionString="LDAP://testdomain3.test.com/CN=Users,
                              DC=testdomain3,DC=test,DC=com" />
    </connectionStrings>
    
  • Configure one ActiveDirectoryMembershipProvider for each domain in the Web.config file specifying at least the connection string name and optionally the credentials (by using connectionUserName and connectionPassword attributes) of an account with permissions necessary to access Active Directory. If you do not specify account credentials, your application's process identity is used to access Active Directory, regardless of whether your application uses impersonation.
  • Ensure that the defaultProvider attribute is set to the domain provider which you are going to use as default domain (if any).
    <membership>
       <providers>
          <add
             name="TestDomain1ADMembershipProvider"
             type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, 
                   Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="TestDomain1ConnectionString"
             connectionUsername="testdomain1\administrator" 
             connectionPassword="password"/>
          <add
             name="TestDomain2ADMembershipProvider"
             type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, 
                   Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="TestDomain2ConnectionString"  
             connectionUsername="testdomain2\administrator" 
             connectionPassword="password"/>
          <add
             name="TestDomain3ADMembershipProvider"
             type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, 
                   Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="TestDomain3ConnectionString"
             connectionUsername="testdomain3\administrator" 
             connectionPassword="password"/>
       </providers>
    </membership>
    
  • On the login page (login.aspx) instead of using login control provided by ASP.NET 2.0, use TextBox server controls to obtain the domain, username and password. Depending upon the domain information get the instance of specific provider and use membership APIs to validate the user as follows.
    // Get the specific provider
    MembershipProvider domainProvider = Membership.Providers["TestDomain1ADMembershipProvider"];
    
    // validate the user
    Bool IsValidate = domainProvider.ValidateUser(UserNameTextBox.Text, PasswordTextBox.Text);
    
  • Encrypt the connectionStrings section in the Web.config file by using protected configuration. Also if you specify user credentials in the ActiveDirectoryMembershipProvider configuration encrypt the membership configuration section as well.


More Information

For more information on using forms authentication with multiple domains in active directory, see “How To: Use Forms Authentication with Active Directory in Multiple Domains in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000021.asp


How do I protect Forms Authentication?

To protect forms authentication you need to encrypt and integrity check the authentication ticket, use SSL to protect user credentials and authentication tickets over the wire, do not persist authentication cookies on the client, enforce strong passwords, use non-reversible password hashes with salt and protect your user store.


Protecting authentication tickets helps to avoid spoofing and impersonation, session hijacking, and elevation of privilege.


Strong passwords help to defend against brute force attacks, and passwords stored as hashes with salt further slow down dictionary attacks, giving time for your detection measures to detect an attack.


To protect forms authentication

  • Ensure that your forms authentication tickets are encrypted and integrity checked by setting protection="All" on the forms element.
  • Use Secure Sockets Layer (SSL) to protect the forms authentication credentials and the forms authentication cookie passed from browser to server by setting requireSSL="true".
  • If you cannot use SSL, consider reducing the cookie lifetime by reducing the timeout value to minimize the time window within which an attacker can use a captured authentication cookie to access your site.
  • If you are in a scenario where you are concerned about cookie hijacking, consider reducing the timeout and setting slidingExpiration="false".
  • Use unique name and path attribute values on the <forms> element.
  • Here is sample of secure forms authentication configuration
    <forms loginUrl="Restricted\login.aspx"  
       protection="All"                  
       requireSSL="true"                 
       timeout="10"                      
       name="AppNameCookie"              
       path="/FormsAuth"                    
       slidingExpiration="true" >        
    </forms>
    
  • Do not persist authentication cookie on the client computer, and do not use it for personalization purposes.
  • Enforce strong passwords and store them as non-reversible password hashes with added salt.
  • When using SQL Server database as user store, protect your authentication login form against SQL injection attacks by validating and constraining input credentials, and by using parameterized stored procedures while accessing the user store.
  • Protect the connection string that points to your user store for example by encrypting the connectionStrings section in your Web.config file.
  • Protect access to the user store by granting appropriate access to only the accounts that require it. As an added measure, locate your user store on a physically separate server from your Web server.


More Information

For more information on securing forms authentication, see “How To: Protect Forms Authentication in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000012.asp


How do I enforce strong passwords using membership feature in ASP.NET 2.0

You can enforce strong passwords using membership by configuring the attributes minRequiredPasswordLength, minRequiredNonAlphanumericCharacters, and passwordStrengthRegularExpression on your membership provider configuration.


Strong passwords help defend against brute force attacks and dictionary attacks.


The default password strength is set to a minimum password length of 7 characters with at least 1 non-alphanumeric character for both SqlMembershipProvider and ActiveDirectoryMembershipProvider.


If you are using the ActiveDirectoryMembershipProvider with Active Directory, your domain password policy is used by default, although you can further strengthen password policy by overriding this with your membership configuration by using the attributes listed earlier. Similarly, if you are using ActiveDirectoryMembershipProvider with ADAM, your local password policy is used, although you can override this with your membership configuration.


If you need to configure your membership provider to enforce specific strong password rules, you can use regular expressions, or you can set specific max and min requirements for numeric, alhpabetic and alphanumeric characters.

Using regular expression

<membership ...>
   <providers>
      <add passwordStrengthRegularExpression= 
                    "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$" .../>
   </providers>
</membership>

Using minimum length and non-alphanumeric character

<membership ...>
   <providers>
      <add minRequiredPasswordLength=10 minRequiredNonalphanumericCharacters=2 .../>
   </providers>
</membership>


More Information

For more information on enforcing strong password, see "How To: Protect Forms Authentication in ASP.NET 2.0" at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000012.asp


How do I protect passwords in user store?

Avoid storing user passwords either in plaintext or encrypted format. Instead, store password hashes with salt. Ensure only required accounts have the access to user store database. Store your credential database on a physically separate server from your Web server.


By storing your password with hashes and salt, you help prevent an attacker who has compromised your user store from obtaining the user passwords and also it slows down an attacker who is attempting to perform a dictionary attack. This gives you additional time to detect and react to the compromise.


By giving access only to required accounts you limit access to your credentials store, which reduces the chances of a compromise.


By locating the credentials store database on a separate physical server you makes it harder for an attacker to compromise your credential store even if he or she manages to take control of your Web server.


Use one of the membership providers that ensure secure credential storage and where possible, specify a hashed password format on your provider configuration.


If you must implement your own user stores, store one-way password hashes with salt. Generate the hash from a combination of the password and a random salt value. Use a hashing algorithm such as SHA256.


What are the issues with Forms Authentication in Web Farm Scenario?

In a Web farm scenario you cannot guarantee which server will handle successive requests. With default settings on each server, if a user is authenticated on one server and the next request goes to another server the authentication ticket will fail the validation and the user will be forced to re-authenticate.


The validationKey and decryptionKey in the <machineKey> section is used for hashing and encryption of the forms authentication ticket. The default value of this keys is “AutoGenerate,IsolateApps”, i.e. the keys are auto generated for each application and they will be different on each server. Hence authentication tickets encrypted and tamper proofed on one machine cannot be decrypted and integrity checked on another machine in a Web farm.


To address this issue, you must ensure that the validationKey and decryptionKey are identical on all machines in the farm.


To do so you must manually generate the validationKey and decryptionKey and copy the key values to all machines in the Web farm. Additionally you must ensure that the name and path attributes in the <forms> element in configuration files on each server share the same value.


If you deploy multiple applications in the Web farm, ensure that you use separate validationKey and decryptionKey values and name and path attribute values in <forms> element for each application, but duplicate each application's validationKey and decryptionKey values and name and path attribute values in the <forms> element across all servers in the farm.


To generate cryptographically random keys, use the RNGCryptoServiceProvider class to generate a cryptographically strong random number. The key must be a minimum of 40 hexadecimal characters (20 bytes) and a maximum of 256 hexadecimal characters (64 bytes) long.

using System;
using System.Text;
using System.Security;
using System.Security.Cryptography;

class App
{
 static void Main(string[] argv) 
 {
    int len = 128;
    if (argv.Length > 0)
        len = int.Parse(argv[0]);
    byte[] buff = new byte[len/2];
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(buff);
    StringBuilder sb = new StringBuilder(len);
    for (int i=0; i<buff.Length; i++)
          sb.Append(string.Format("{0:X2}", buff[i]));
    Console.WriteLine(sb);
 }
}


Use the generated keys to configure the machineKey settings in your Web.config file as follows. Use separate keys for validationKey and decryptpionKey.

 <machineKey validationKey="Hsbfb636576sahfj\mfhhshnj234235"  
             decryptionKey="shakh7857jkjjco985\fhhegf476343" 
             validation="SHA1" decryption="Auto" />


More Information

For information about how to generate manual key values and machine key configuration, see “How To: Configure MachineKey in ASP.NET 2.0” please refer to http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000007.asp


How do I implement single sign on using forms authentication?

If you need a single sign on to work across multiple applications located in separate virtual directories, you need to share a common authentication ticket which can be decrypted and integrity checked by every application.


For this you must manually generate validationKey and decryptionKey values and set these values on the <machineKey> element in the machine level Web.config file. Additionally you must ensure that the name and path attributes in the <forms> element is same for each application.


To generate cryptographically random keys, use the RNGCryptoServiceProvider class to generate a cryptographically strong random number. The key must be a minimum of 40 hexadecimal characters (20 bytes) and a maximum of 256 hexadecimal characters (64 bytes) long.

using System;
using System.Text;
using System.Security;
using System.Security.Cryptography;
class App
{
 static void Main(string[] argv) 
 {
   int len = 128;
   if (argv.Length > 0)
       len = int.Parse(argv[0]);
   byte[] buff = new byte[len/2];
   RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
   rng.GetBytes(buff);
   StringBuilder sb = new StringBuilder(len);
   for (int i=0; i<buff.Length; i++)
         sb.Append(string.Format("{0:X2}", buff[i]));
   Console.WriteLine(sb);
 }
}


Use the generated keys to configure machineKey settings in your Web.config file as follows. Use separate keys for validationKey and decryptpionKey.

<machineKey validationKey="Hsbfb636576sahfj\mfhhshnj234235"  
            decryptionKey="shakh7857jkjjco985\fhhegf476343" 
            validation="SHA1" decryption="Auto" />


More Information

For information about how to generate manual key values and MachineKey configuration, see “How To: Configure MachineKey in ASP.NET 2.0 at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000007.asp


How do I use my custom user / identity store with forms authentication?

Implement a custom membership provider inheriting from the MembershipProvider abstract base class. Use this custom provider along with the login controls to implement forms authentication.


The membership feature provides a consistent API for user authentication and user management. The login controls work with membership.


To use a custom user / identify store with forms authentication.

  • Implement a custom membership provider that inherits from the MembershipProvider abstract base class. This custom provider class should interact with your custom user / identity store.
  • Configure the connection string for your provider (if required) in the connectionStrings section
  • Configure the custom provider in your application’s Web.config file and set the defaultProvider as your custom provider as follows
    <membership defaultProvider="MyCustomMembershipProvider" >
      <providers>
        <clear/>
        <add name="MyCustomMembershipProvider"
             applicationName="MyAppName"
             type="CustomMembershipProvider, CustomDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </membership>
    
  • Configure your application for forms authentication in the Web.Config file as follows
    <authentication mode="Forms">
    
  • Configure your application to deny access to unauthenticated users in Web.config file as follows
    <authorization> 
      <deny users="?" />
    </authorization>
    
  • Use the Login and CreateUserWizard controls for creating login page (login.aspx) for forms authentication.


More Information

For more information on using the membership feature, see “How To: Use Membership in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000022.asp


How do I configure account lockout using membership feature in ASP.Net 2.0?

If you are using the SqlMembershipProvideror ActiveDirectoryMembershipProvider, you use the maxInvalidPasswordAttempts and passwordAttemptWindows attributes on the provider configuration. By default, these values are 5 and 10, respectively. This means you get 5 invalid attempts within 10 minutes before you are locked out.


If you are using the ActiveDirectoryMembershipProvider, your domain or local security policy controls the password lockout. Note that if an account is locked out by the provider, it is not locked out within Active Directory, so you could still log on to Windows with the account. However, the ActiveDirectoryMembershipProvider treats the account as locked out, so the user cannot logon through an application that uses the provider until the lockout duration elapses. Accounts locked out by the provider are re-enabled after a time interval defined by the attributeMapFailedPasswordAnswerLockoutTime attribute. The default is 30 minutes. Alternatively, you can write code that calls the UnlockUser method on the MembershipUser object.


Here is how you configure account lockout settings

<membership defaultProvider=NewProvider>
   <providers>
      <add name=NewProvider maxInvalidPasswordAttempts=3 and passwordAttemptWindows=10 …/>
   <providers>
</membership>


More Information

For more information on configuring account lockout, see “How To: Use Membership in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000022.asp


When and how do I use windows authentication in ASP.NET 2.0?

Your ASP.NET application should use Windows authentication when your users have Windows accounts that can be authenticated by a server. The accounts can be local Windows accounts or domain accounts.


To use Windows authentication in ASP.NET in conjunction with Integrated Windows authentication in IIS

  • Configure the virtual directory on IIS to disable anonymous access and configure it to use Integrated Windows authentication alone (by default anonymous access is enabled).
  • Configure your application's Web.config for Windows authentication (the default)
    <authentication mode="Windows">
    


More Information

For more information about using windows authentication and features like impersonation provided by windows authentication, see “How To: Use Windows Authentication in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGHT000025.asp


For additional information on how Windows authentication works in ASP.NET, see “Explained: Windows Authentication in ASP.NET 2.0” at http://msdn.microsoft.com/library/en-us/dnpag2/html/PAGExplained0001.asp


When and how do I use Kerberos authentication in ASP.NET 2.0?

If all your computers are in a Windows Server 2000 or later domain and your clients are using Internet Explorer version 5.5 or later, you can use Kerberos authentication in ASP.NET.


To use Kerberos Authentication in ASP.NET

  • Configure your application's virtual directory in IIS to disable anonymous access and configure it to use Integrated Windows authentication alone (by default anonymous access is enabled).
  • Configure your application's Web.config for Windows authentication (the default)
    <authentication mode="Windows">
    


If you run your application using a domain service account, you must register a service principal name (SPN) for that account in Active Directory to associate the account with the HTTP service on the Web server. To register an SPN, use the Setspn.exe utility as follows

setspn -A HTTP/webservername domain\customAccountName 
setspn -A HTTP/webservername.fullyqualifieddomainname domain\customAccountName 


Note that you cannot have multiple Web applications with the same host name if you want them to have multiple identities and to use Kerberos authentication. This is an HTTP limitation, not a Kerberos limitation. The workaround is to have multiple Domain Name System (DNS) names for the same host, and start the URLs for each Web application with a different DNS name. For example, you would use http://app1 and http://app2 instead of http://site/app1 and http://site/app2.


Note: If your clients run Internet Explorer 6, you must enable the browser to respond to a negotiate challenge and perform Kerberos authentication. To do this, select the Enable Integrated Windows Authentication check box in the Security section of the Advanced tab of the Internet Options menu, and then restart the browser. Administrators can enable Integrated Windows authentication by setting the EnableNegotiate DWORD value to 1 in the following registry key: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings

Personal tools