.gif)
J.D. Meier, Blaine Wastell, Prashant Bansode, Alex Mackman
Microsoft Corporation
November 2007
Applies To
Contents
Authentication
Authorization
Auditing and Logging
Code Access Security
Impersonation/Delegation
Configuration
Exception Handling
Data Access
Input / Data Validation
Sensitive Data
Strong Naming and Signing
Obfuscation
Authentication
- What’s new in ASP.NET in terms of authentication?
- How do I decide my Authentication strategy in ASP.NET?
- How do I use Forms Authentication with SQL Server
database?
- How do I use Forms Authentication with Active
Directory?
- How do I enable Forms Authentication to work with
multiple Active Directory domains?
- How do I protect Forms Authentication?
- How do I enforce strong passwords using membership
feature in ASP.NET 2.0?
- How do I protect passwords in user store?
- What are the issues with Forms Authentication in Web
Farm Scenario?
- How do I implement single sign on using forms
authentication?
- How do I use my custom user / identity store with forms
authentication?
- How do I configure account lockout using membership
feature in ASP.Net 2.0?
- When and how do I use windows authentication in ASP.NET
2.0?
- When and how do I use Kerberos authentication in
ASP.NET 2.0?
What's new in ASP.NET 2.0 in terms of
Authentication?
ASP.NET 2.0 introduces a new feature called Membership,
which provides a consistent and simple APIs for user storage and management and
enables easy implementation of Forms Authentication.
The membership feature supports 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 2.0 provides built in Login controls like Login,
LoginView, LoginName, CreateUserWizard, ChangePassword etc which by default
work with Membership feature, making Forms Authentication implementation
simpler.
Additionally you can use membership feature APIs like CreateUser,
ValidateUser, etc for manual user management and authentication.
More Information
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 using ActiveDirectoryMembershipProvider membership
provider.
If your user accounts are in a SQL Server database, use
forms authentication using the SqlMembershipProvider membership provider.
If your user accounts are in ADAM, use forms authentication
using the ActiveDirectoryMembershipProvider membership provider.
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.
More Information
How do I use Forms Authentication with SQL Server
database?
Use the built-in SqlMembershipProvider of the new Membership
feature in ASP.NET 2.0 along with login control for forms authentication
with user store in SQL server database.
The membership feature provides a consistent and simple APIs
for user authentication and user management. The login control by default, work
with the Membership feature. This control reduces the custom code required to
make Forms Authentication work.
For using forms authentication with a SQL Server database as
the user store,
- -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
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 connectionStrings
section pointing 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, configured. Ensure that the defaultProvider
attribute is set to the provider configured 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
for creating login page (login.aspx) for forms authentication.
- Encrypt the connectionStrings configuration section
using protected configuration feature.
More Information
How do I use Forms Authentication with Active
Directory?
Use the built-in ActiveDirectoryMembershipProvider of
the new Membership feature in ASP.NET 2.0 along with login control for
forms authentication with Active Directory.
The membership feature provides a consistent and simple APIs
for user authentication and user management. The login control by default, work
with the Membership feature. This control reduces the custom code required to
make Forms Authentication work.
For using forms authentication with Active Directory as the
user store,
- Configure your application for Forms Authentication in
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 LDAP connection string in connectionStrings
section pointing to the Active Directory to be used in Web.config file as
follows.
<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 capable of accessing
Active Directory with the necessary permissions. 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. Either the account specified in the Web.config file or your
process account must have the appropriate permissions to access Active
Directory.
- 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 for creating login page
(login.aspx) for forms authentication.
- Encrypt the connectionStrings section using the
protected configuration feature. Also if you specify user credentials in
the ActiveDirectoryMembershipProvider configuration encrypt the
membership configuration section as well.
More Information
How do I enable forms authentication to work with
multiple Active Directory domains?
Configure ActiveDirectoryMembershipProvider for each
domain. Create a custom login form using TextBox server control to get
user credentials and domain information. Depending upon the domain information,
use the domain specific ActiveDirectoryMembershipProvider instance for manually
authenticating the user.
The Membership feature by default works with a single
domain only (configured as defaultProvider). Also you cannot use the
login controls in a multiple domain scenario, as they work with only the
default membership provider configured. Hence you need to use custom login form
using TextBox server control.
Here is how to get the forms authentication working with
multiple domains.
- Configure your application for Forms Authentication in
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 connections strings for multiple domains,
corresponding one for each in Web.config file as follows.
<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, using connectionUserName
and connectionPassword attributes, of an account capable of accessing
Active Directory with the necessary permissions in that domain. 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. Either the account specified in the Web.config file or
your process account must have the appropriate permissions to access
Active Directory in that domain.
- 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 control to get
information about the domain, user and password. Depending upon the domain
information get the instance of specific provider and use Membership APIs
for validating / authenticating 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 using the
protected configuration feature. Also if you specify user credentials in
the ActiveDirectoryMembershipProvider configuration encrypt the
membership configuration section as well.
More Information
How do I protect Forms Authentication?
For protecting forms authentication you need to encrypt and
integrity check the authentication ticket, use SSL to protect user credentials
and authentication ticket over wire, do not persist authentication cookie at
client side, enforce strong passwords, use non-reversible password hashes with
salt and protect your user store.
Protecting authentication tickets helps to avoid
unauthorized spoofing and impersonation, session hijacking, and elevation of
privilege.
Strong passwords help in defending against brute force
attacks, and password stored as hashes with salt further slows down dictionary
attacks hence giving time for countermeasure to react.
Here is how you protect forms authentication
- Do not persist authentication cookie on the client
computer, and do not use it for personalization purposes.
- Enforce strong passwords and store it as non-reversible
password hashes.
- 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 point 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. Additionally store should be
residing on physically separate server.
More Information
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 in defending 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.
Here is how you configure membership provider for enforcing
strong password.
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
How do I protect passwords in user store?
For protecting password in user store, you should not store
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.
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 it limits access
to your credentials store, hence less chances of attacker compromising it.
By locating the credentials store database on a separate
physical server 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 an algorithm such as SHA256.
More Information
What are the issues with Forms Authentication
in a Web Farm Scenario?
In a web farm scenario you cannot guarantee which server
will handle successive requests. With default settings of each server, if user
is authenticated on one server and the next request goes to another server the
authentication ticket will fail the validation and force user to re-authenticate.
The validationKey and decryptionKey in <machineKey>
section is used for hashing and encryption of the form’s 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 web farm.
To address this issue, validationKey and decryptionKey
must be identical on all machines
For this you must manually generate 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 <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 keys generated thus to configure in machine key
settings in machine.config / Web.config file as follows. Use separate keys for validationKey
and decryptpionKey. Here is the sample configuration.
<machineKey validationKey="Hsbfb636576sahfj\mfhhshnj234235"
decryptionKey="shakh7857jkjjco985\fhhegf476343"
validation="SHA1" decryption="Auto" />
More Information
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 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 keys generated thus to configure in machine key
settings in machine.config / web.config file as follows. Use separate keys for validationKey
and decryptpionKey. Here is the sample configuration
<machineKey validationKey="Hsbfb636576sahfj\mfhhshnj234235"
decryptionKey="shakh7857jkjjco985\fhhegf476343"
validation="SHA1" decryption="Auto" />
More Information
How do I use my custom user / identity store with
forms authentication?
Implement a custom membership provider inheriting from MembershipProvider
abstract base class which works with the custom user/identity store. Use this
custom provider along with login control for forms authentication with custom
user/identity store.
The membership feature provides a consistent and simple APIs
for user authentication and user management. The login control by default, work
with the Membership feature. This control reduces the custom code required to
make Forms Authentication work.
Here is how you can use 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 connection string for your provider (if
required) in 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
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
How do I configure account lockout using
membership feature in ASP.NET 2.0?
If you are using the SqlMembershipProvider or
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, 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
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.
For using Windows Authentication in ASP.NET in conjunction
with Integrated Windows authentication on IIS
More Information
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.
For using Kerberos Authentication in ASP.NET
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
Authorization
- What's new in ASP.NET 2.0 in terms of Authorization?
- What's the difference between URL Authorization, File
Authorization and Role Authorization?
- How do I use URL Authorization in ASP.NET 2.0?
- How do I use File Authorization in ASP.NET 2.0?
- How do I use Role Authorization in ASP.NET 2.0?
- How is the AuthorizationStoreRoleProvider different
from Authorization Manager APIs?
- How do I use Windows Groups for role authorization in
ASP.NET 2.0?
- How do I use my custom role store for roles
authorization?
- How do I cache roles in ASP.NET 2.0?
- How do I protect authorization cookie when using role
caching in ASP.NET 2.0?
- How do I lock authorization settings?
What's new in ASP.NET 2.0 in terms of
Authorization?
ASP.NET 2.0 introduces a new feature called Role Manager,
which enables easy implementation of Roles Authorization in ASP.NET 2.0.
The Role Manager feature supports provider model with the WindowsTokenRoleProvider
for Windows groups in AD, SqlRoleProvider for role store in
SQL Server database and AuthorizationStoreRoleProvider for
AzMan policy role store in Active Directory, Active Directory Application Mode
(ADAM) and XML provided as built-in providers. The provider model is extensible
and you can create custom providers for your custom role stores.
The Role Manager feature provides APIs like CreateRole,
AddUserToRole, IsUserInRole etc for roles
management and roles authorization.
Additionally ASP.NET 2.0 role manager provides roles caching
feature, which caches roles read from the roles store for a user and reuses
them on subsequent roles checks, thus improving the performance.
The Role Manager is not enabled by default. Therefore,
before you can use the Role manager you need to explicitly enable it in your
application's web.config
More Information
What's the difference between URL
Authorization, File Authorization and Role Authorization?
- URL Authorization is configured by settings within
machine and application configuration files. It allows you to restrict
access to specific files and folders within your application's Uniform
Resource Identifier (URI) namespace. For example, you can selectively deny
or allow access to specific files or folders (addressed by means of a URL)
to nominated users. You can also restrict access based on the user's role
membership or User's Identity. URL Authorization requires an authenticated
identity. This can be obtained by a Windows or ticket-based authentication
scheme.
Important: When using roles in URL authorization, the role manager
should be enabled and configured for using correct role store.
- File Authorization applies only if you use one of
the IIS-supplied Windows authentication mechanisms to authenticate callers
and ASP.NET is configured for Windows authentication. For file types
mapped by IIS to the ASP.NET ISAPI extension (Aspnet_isapi.dll), automatic
access checks are performed using the authenticated user's Windows access
token (which may be IUSR_MACHINE for anonymous users) against the access
control list (ACL) attached to the requested ASP.NET file.
- Roles authorization can be used for fine grained
authorization to control access to resources and operations and they can
be configured both declaratively and programmatically. .NET Framework 2.0
provides a new Role
Manager feature for role based authorization.
How do I use URL Authorization in ASP.NET 2.0?
Configure URL authorization, use an <authorization>
element in Web.config and specify which user and/or role names are allowed
access to the current directory or the nominated directory or file.
URL authorization allows you to restrict access to specific
files and folders within your application's Uniform Resource Identifier (URI)
namespace using the authenticated user's name or user's role membership held in
the HttpContext.User object. ASP.NET version 2.0 on Windows Server 2003
protects all files in a given directory, even those not mapped to ASP.NET, such
as .html, .gif, and .jpg files.
This can be done by configuring the <authorization>
element in Web.config as follows. Authorization settings in Web.config refer to
all of the files in the current directory and all subdirectories unless a
subdirectory contains its own Web.config with an <authorization>
element. In this case, the settings in the subdirectory override the parent
directory settings
<system.web>
….
<authorization>
<allow users="userName1, userName2" />
<allow roles="roleName1, roleName2" />
<deny users="*" />
</authorization>
….
</system.web>
Important: When using roles in URL authorization, the
role manager should be enabled and configured for using correct role store.
Note: URL authorization can be used for both forms
authentication and Windows authentication. In the case of Windows
authentication, user names take the form "DomainName\WindowsUserName"
and role names take the form "DomainName\WindowsGroupName". The local
administrators group is referred to as "BUILTIN\Administrators". The
local users group is referred to as "BUILTIN\Users". The following
example shows Windows users and Windows roles.
How do I use File Authorization in ASP.NET 2.0?
Configure the access control lists (ACLs) for the right
identities to have appropriate permissions on your ASP.NET files. The FileAuthorizationModule
automatically performs access checks against the requested file.
The identities that you need to consider for file
authorization:
- Your Web application identity. If you are using a
custom service account to run your ASP.NET application, you can grant the
appropriate permissions to the IIS metabase and to the file system by
running Aspnet_regiis.exe with the–ga switch.
- Your application's users. ASP.NET file
authorization performs access checks for file types mapped by IIS to the
ASP.NET ISAPI extension (Aspnet_isapi.dll). If you are using Windows
authentication, the authenticated user's Windows access token (which may
be IUSR_MACHINE for anonymous users) is checked against the ACL attached
to the requested ASP.NET file. If you are using forms authentication,
access is checked against IUSR_MACHINE.
Note: File Authorization works automatically when
using Windows Authentication; Impersonation is not required.
How do I use Role Authorization in ASP.NET 2.0?
Use Role manager feature with built-in providers introduced
in ASP.NET 2.0 for role authorization. You can do role authorization in code by
performing explicit role checks using Role Manager APIs like IsUserInRole
etc.
The Role Manager feature provides a consistent and simple
APIs for role authorization and role management. And it supports built-in
providers like WindowsTokenRoleProvider for Windows groups as
roles, SqlRoleProvider for roles store in SQL Server database
and AuthorizationStoreRoleProvider for AzMan policy roles store
in Active Directory, Active Directory Application Mode (ADAM) or XML.
For using role authorization do the following
- Add a connection string to the <connectionStrings>
section to point to your roles store. If you are using the AuthorizationStoreRoleProvider,
this is an LDAP query string pointing to your Authorization Manager Policy
store in Active Directory or ADAM. If you are using the SqlRoleProvider,
this is a database connection string that points to your role store
database.
- Configure the role provider and make sure the defaultProvider
is set correctly to point to the configured role provider. Here is sample
for SqlRoleProvider
<configuration>
<connectionStrings>
<add name="SqlRoleManagerConnection"
connectionString="Data Source=sqlinstance;
Initial Catalog=aspnetdb;Integrated
Security=SSPI;">
</add>
</connectionStrings>
</configuration>
<roleManager enabled="true"
defaultProvider="SqlRoleManager">
<providers>
<add name="SqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="SqlRoleManagerConnection"
applicationName="MyApplication" />
</providers>
</roleManager>
- Use Role Manager APIs for accessing and validating the
role membership for the user. By default it uses the HttpContext.User
object for user identity.
bool isInRole
= Roles.IsUserInRole("TestRole");
- You can also do Role Authorization using
PrincipalPermission demands
More Information
How is the AuthorizationStoreRoleProvider different from Authorization Manager APIs?
AuthorizationStoreRoleProvider only exposes a subset
of Authorization Manager's functionality. For example, you cannot use
Authorization Manager's authorization business logic, such as tasks and
operations.
You can use AuthorizationStoreRoleProvider only for
role membership checks. The benefit of using AuthorizationStoreRoleProvider
is that it gives a consistent APIs for role authorization, hence at development
time any role store can be used and then in production it can be deployed on
AzMan policy store without affecting the code.
If you have to use business logic of Authorization manager
you will need to use the Authorization Manager APIs directly
More Information
How do I use Windows Groups for role
authorization in ASP.NET 2.0?
If you use Windows authentication, you can use the ASP.NET
2.0 Role Manager feature with the WindowsTokenRoleProvider for
role-based authorization using Windows Groups.
Enable role manager by setting the enabled attribute
on the <roleManager> element to true. Note that the
Machine.config file contains a default configuration for a WindowsTokenRoleProvider
instance named AspNetWindowsTokenRoleProvider. You can use this provider
instance and set it as the default provider by modifying your Web.config file
as follows.
<system.web>
<roleManager enabled="true"
defaultProvider="AspNetWindowsTokenRoleProvider" />
</system.web>
To check role membership to authorize callers, use the Role
Manager APIs such as IsUserInRole.
if(Roles.IsUserInRole("Readers")){}; More Information
How do I use my custom role store for roles
authorization?
Implement a custom roles provider inheriting from RoleProvider
abstract base class which works with the custom role store. Use this custom
provider along with Role Manager APIs for roles authorization using your custom
role store.
The role manager feature provides a consistent and simple
APIs for role authorization and role management.
Here is how you can use custom role store for roles
authorization.
- Implement a custom membership provider that inherits from
the RoleProvider abstract base class. This custom provider class
should interact with your custom role store.
- Configure connection string for your provider (if
required) in connectionStrings section
- Configure the custom provider in your application’s
Web.config file, enable role manager and set the defaultProvider as
your custom provider as follows
<roleManager
enabled=true defaultProvider="MyCustomMembershipProvider" >
<providers>
<add name="MyCustomMembershipProvider"
applicationName="MyAppName"
type="CustomRoleProvider, CustomDll, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</membership>
- Use Role Manager APIs for accessing and validating the
role membership for the user. By default it uses the HttpContext.User
object for user identity.
bool isInRole = Roles.IsUserInRole("TestRole");
More Information
How do I cache roles in ASP.NET 2.0?
If a user's browser accepts cookies, you can cache role
information for that user in a cookie. For this set the cacheRolesInCookie
attribute to true on <roleManager> element. On each page
request, ASP.NET reads the role information for that user from the cookie.
Role caching can improve application performance by reducing
the amount of communication required with the data source to retrieve role
information. If the role information for a user is too long to store in a
cookie, ASP.NET stores only the most recently used role information in the
cookie and then looks up additional role information in the data source as and
when required.
To configure and enable role caching, set cacheRoleInCookie
to true on the <roleManager> element as shown here.
<roleManager enabled="true"
cacheRolesInCookie="true" .../>
Note: When using role caching its important to
protect the authorization cookie.
More Information
How do I protect authorization cookie when using
role caching in ASP.NET 2.0?
For protecting authorization cookie you need to encrypt and
integrity check the authorization cookie, use SSL to protect authorization
cookie over wire, do not persist authorization cookie client side
When using role caching securing the roles cookie is of
prime importance. This is to stop users modifying the list of roles to which
they belong, and to stop intruders from gaining information about the roles
used by your application
- Ensure the cookie is encrypted and integrity checked by
setting the cookieProtection attribute to All.
- Ensure that the authorization cookie is only
transmitted over HTTPS connections by setting cookieRequireSSL to true.
- Ensure that the Roles cookie is not persisted on client
computer by setting createPersistentCookie to false.
- If you cannot use SSL, consider reducing the cookie
lifetime by reducing the cookieTimeout value to minimize the time
window within which an attacker can use a captured roles cookie to access
your site with privileged rights.
- If you are in a scenario where you are concerned about
cookie hijacking, consider reducing the timeout and setting slidingExpiration="false".
Here is a sample of secured role caching
<roleManager enabled="true"
cacheRolesInCookie="true"
cookieName=".ASPROLES"
cookieTimeout="30"
cookiePath="/"
cookieRequireSSL="true"
cookieSlidingExpiration="true"
cookieProtection="All"
createPersistentCookie="false">
</roleManager>
More Information
How do I lock authorization settings?
Server administrators can lock authorization settings by
using the <authorization> element in the machine-level Web.config file.
This ensures that an individual application cannot override machine-level
policy. To lock authorization settings, surround the <authorization>
element inside a <location> element and set
allowOverride="false" as shown here.
<location allowOverride="false">
<system.web>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
</system.web>
</location>
Auditing and Logging
- What's new in ASP.NET 2.0 in terms of Auditing and
Logging?
- How do I use the Health Monitoring feature in ASP.NET
2.0?
- What all security events do health monitoring feature
logs by default?
- How do I instrument my application for security?
- When writing to a new event source from my ASP.NET
application running under the Network service security context, I get
registry permission exception. Why is this and how do I correct this?
- How do I protect audit and log files?
What's new in ASP.NET 2.0 in terms of
Auditing and Logging?
ASP.NET version 2.0 introduces the health monitoring system.
It supports many standard events that you can use to monitor the health of your
application. Examples of security related events include logon failures when
using the ASP.NET membership system, attempts to tamper with or reuse forms
authentication tickets, and infrastructure events such as disk access failures
etc.
By default, all Web error and Audit failure events are
logged to the windows event log. Health monitoring uses event providers to
deliver event notifications. The following event providers are available out of
box:
- SimpleMailWebEventProvider. This provider sends
e-mail for event notifications.
- TemplatedMailWebEventProvider. This provider uses
templates to define and format e-mail messages sent for event
notifications.
- SqlWebEventProvider. This provider logs event
details to a SQL Server database. If you use this provider, you should
encrypt the connection string in your Web.config file by using the
Aspnet_regiis.exe tool.
- EventLogWebEventProvider. This provider logs events
to the Windows application event log.
- TraceWebEventProvider. This provider logs events as
ASP.NET trace messages.
- WmiWebEventProvider. This provider maps ASP.NET
health monitoring events to Windows Management Instrumentation (WMI)
events.
In addition you can also create custom event providers to
write events to custom stores by creating a class that inherits from System.Web.Management.WebEventProvider.
You can also create custom events to instrument your
application for other security and non-security related notable events and log
them using Health Monitoring feature.
More Information
How do I use the Health monitoring feature in
ASP.NET 2.0?
You can use the health monitoring feature introduced in
ASP.NET version 2.0 to instrument key application events. You can choose where
to log events by configuring an appropriate provider. You can instrument
built-in events or create custom events by deriving from one of the provided
base events to monitor specific business logic or operations in your Web
application.
By default health monitoring is enabled for ASP.NET
applications and it logs all Web Error and Audit failure events to Windows
Event log.
Here is how you use Health Monitoring feature
- Identify all the security related events that you need to
log for your application, including the default events available with
health monitoring and custom security events specific to your application.
- Configure event mappings for all the identified events in
the web.config file as follows; here Membership Authentication Success
event is mapped.
<healthMonitoring
enabled=”true”>
….
<eventMappings>
<add name="LoginAudit"
type="System.Web.Management.
AuditMembershipAuthenticationSuccess, System.Web, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
startEventCode="0"
endEventCode="2147483647" />
</eventMappings>
….
</healthMonitoring>
- Identify the event store where you want to log the
security events, you can choose multiple event stores for logging events
based on event criticality etc.
- Configure event providers corresponding to event store
identified in web.config file as follows, here windows event log is used
as event store
<healthMonitoring
enabled=”true”>
….
<providers>
<add name="EventLogProvider"
type="System.Web.Management.EventLogWebEventProvider, System.Web,Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
….
</healthMonitoring>
- Configure <rules> to specify as to which security
event is to be logged through which provider (event store).
<healthMonitoring
enabled=”true”>
….
<rules>
<add provider="EventLogProvider" name="Login
Audits" eventName="LoginAudit" />
</rules>
….
</healthMonitoring>
Now when ever a membership authentication in your
application is successful an event is raised by membership feature, which will
be logged to Windows Event log automatically.
More Information
What all security events do health
monitoring feature logs by default?
By default, health monitoring audits the most critical
security events which are those of types WebErrorEvent and WebFailureAuditEvent
(including its descendants, WebAuthenticationFailureAuditEvent and
WebViewStateFailureAuditEvent). These events and are logged to the Windows
Event log.
WebAuthenticationFailureAuditEvent is logged for Forms
based authentication failures, Membership Authentication failures because of
invalid user credentials, passing of expired authentication ticket and passing
of invalid authentication ticket. This can be used for identifying dictionary
attacks, brute force attacks etc.
WebViewStateFailureAuditEvent is logged for invalid
view state failures. This can be used for identifying ViewState tampering.
WebFailureAuditEvent is logged for authorization
failures for accessing files, folders, or any other resources to which users
don’t have access. This can be used identifying attacks on the application.
WebErrorEvent is logged for any error occurred during
application compilation and execution including configuration errors. This can
be used to identify any changes made by an attacker to the application.
More Information
How do I instrument my application for security?
To instrument your application for security, understand the
security critical events logged by default. Analyze the standard available
security events which are not logged by default, if you need to log them.
Additionally create custom event to instrument application specific security
events.
Tracking of security related events is very important for
deducing any attack on the application and to retrace in case an application is
compromised.
To instrument your application for security is three step
process.
- Identify all the events that are logged by default, the
ASP.NET health monitoring system is configured to report all
security-related error events (WebFailureAuditEvent and its
descendants), and all infrastructure-related error events, to the Windows
event log (WebBaseErrorEvent and its descendants). It monitors all
the Forms Authentication, Authorization, ViewState failure events and also
monitors application error events.
- There are number of important security events that are
available with health monitoring by default, but not logged. These events
can be used to detect potential attacks on your application. Review the
events and identify the ones which your application needs to monitor. Here
you have Life time events, Forms Authentication Success events,
Authorization Success events and Web heart beat events.
- In addition to standard events you need to monitor other
important security events specific to your application. These events can
improve your ability to detect and understand attacks on your application.
You can create custom events to monitor more authorization specific event,
session management events, user management events, and any application
specific critical operations monitoring events.
More Information
When writing to a new event source from my
ASP.NET application running under the Network service security context, I get
registry permission exception. Why is this and how do I correct this?
On Windows Server 2003, ASP.NET runs by default using the
Network Service account. This account has the required privileges to write to
any existing event source in the Application event log, but not to create a new
event source. The first time your application tries to write to the event log,
it checks to see if an event source for your application (typically the
application name) already exists. If not, it tries to create it. To create an
event source, your ASP.NET account needs permissions to create a new registry
entry beneath the following key: HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\.
To enable your ASP.NET application to write to the event log
using new event source, you have two options:
- Grant your ASP.NET process account (or impersonated
identity if your application uses impersonation) permissions on the
following registry key: HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\.
- Create the event source at application install time when
administrator privileges are available. You can use a .NET installer
class, which can be instantiated by the Windows Installer (if you are
using .msi deployment) or by the InstallUtil.exe system utility.
Note: When you use the event log provider with
ASP.NET health monitoring, events are logged by using an event source named
"ASP.NET <<.Net Version Number>>". This event source is
created when you install the .NET Framework. This is not configurable and you
cannot change the event source used by health monitoring events.
More Information
How do I protect audit and log files?
Secure audit and log files using Windows ACLs and restrict
access to the log files. If you log events to SQL Server or to some custom
event sink, use appropriate access controls to limit access to the event data.
For example, grant write access to the account or accounts used by your
application, grant full control to administrators, and read-only access to
operators.
This makes it more difficult for attackers to tamper with
log files to cover their tracks. Minimize the number of individuals who can
manipulate the log files. Authorize access only to highly trusted accounts such
as administrators.
Code Access Security
- What's new in ASP.NET 2.0 in terms of Code Access
Security?
- How do I use Code Access Security with ASP.NET?
- How do I create a custom trust level for ASP.NET?
- What are the permissions at the various trust levels?
- How do I write partial trust applications?
- When should I put assemblies in GAC, what are security
implications?
What's new in ASP.NET 2.0 in terms of Code
Access Security?
The main differences between ASP.NET 1.1 and ASP.NET 2.0 for
Code Access Security are the following:
- A new class of evidence (GacEvidence) tells you whether an
assembly was loaded from the global assembly cache (GAC).
- OLEDB managed provider no longer requires full trust
callers - they just need OleDbPermission - now granted to High and
Medium trust ASP.NET Applications
- Now SqlPermission available on medium trust, which is
beneficial for hosting environments.
- SmtpPermission is available at Full, High, and
Medium trust levels. This allows applications to send e-mail.
- New permission types DataProtectionPermission which
controls the ability to use encryption/decryption with DPAPI.
- All the Assemblies installed in GAC by default get full
trust.
- In .Net 2.0, demands for identity permissions will always
succeed in FullTrust.
- Improved protection of public APIs (new security actions
DemandChoice and LinkDemandChoice that allow use of multiple permission
sets)
- Expanded System.Security.SecurityException type,
Now possible to tell precisely what failed and why (includes failed
assembly info – security action that failed, failed assembly’s permission
set grant)
How do I use Code Access Security with ASP.NET?
Administrators can use code access security trust levels
with ASP.NET to isolate applications and to restrict which resource types they
can access and which privileged operations they can perform.
By default all ASP.NET applications run at Full trust level.
You should worry about code access security only when you are developing /
deploying applications in partial trust, as in case of ISVs hosting multiple
applications on the same server from various users / organizations that do not
trust each other. For using code access security do the following.
More Information
How do I create a custom trust level for
ASP.NET?
Create a custom trust file based on standard trust file that
most closely matches your application requirements. Add / Remove the
permissions in the custom trust file depending upon your requirements.
From security perspective, you should give your applications
only the required permissions and nothing more. This is important because even
if your application is compromised an attacker won’t be able to access
resources other than permission given to your application.
Here is how you create a custom trust level.
- Identify the trust level that satisfies most of your
application's permission requirements.
- Copy the trust policy file of that trust level from
%windir%\Microsoft.NET\Framework\{version}\CONFIG\ to a file named
Web_CustomTrust.config in the same directory.
- Add or remove permissions from the custom trust policy
file such that your requirements are satisfied. For example, to add the
registry permission to a custom trust policy file:
Add a <SecurityClass> element.
<SecurityClass Name="RegistryPermission"
Description="System.Security.Permissions.RegistryPermission,
mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089"/>
Add an <IPermission> element to the
"ASP.Net" named permission set.
<PermissionSet
class="NamedPermissionSet"
version="1"
Name="ASP.Net">
. . .
<IPermission
class="RegistryPermission"
version="1"
Unrestricted="true" />
. . .
</PermissionSet>
- Configure your application's root Web.config file to make
your application use the custom trust policy file.
...
<location allowOverride="false">
<system.web>
<securityPolicy>
<trustLevel name="Custom" policyFile="web_CustomTrust.config"/>
</securityPolicy>
<trust level="Custom" originUrl="" />
</system.web>
</location>
Now your application is ready to use the custom trust
policy.
More Information
What are the permissions at the various trust
levels?
The key capabilities and restrictions for each trust level are
summarized in the following table.
| Trust Level | Key capabilities and restrictions |
| Full | - This is the default trust level. No restrictions are
imposed by code access security.
|
| High | - No unmanaged code.
- No enterprise services.
- Can access SQL Server and OLEDB data sources.
- Can send e-mail by using SMTP servers.
Very limited reflection permissions.
- No ability to invoke code by using reflection.
- A broad set of other framework features are available.
Applications have full access to the file system and to sockets.
|
| Medium | - Permissions are limited to what the application can
access within the directory structure of the application.
- No file access is permitted outside of the application's
virtual directory hierarchy.
- Can access SQL Server.
- Can use OLEDN data sources only OledbPermission is
required.
- Can send e-mail by using SMTP servers.
- Limited rights to certain common environment variables.
- No reflection permissions whatsoever.
- No sockets permission.
- To access Web resources, you must explicitly add
endpoint URLs — either in the originUrl attribute of the <trust>
element or inside the policy file.
|
| Low | - Intended to model the concept of a read-only application
with no network connectivity.
- Read only access for file I/O within the application's
virtual directory structure
|
| Minimal | - Execute only.
- No ability to change the IPrincipal on a thread or on
the HttpContext.
|
More Information
How do I write partial trust applications?
In ASP.NET you can write partially trusted code by using
Code Access security. For this first you need to identify the trust level which
you want target for your partially trusted code. If any of the standard partial
trust levels like High, Medium, Low etc do not match your requirement then you
can create custom trust policy as per your partial trust requirement and use
the same.
The second option is to choose one of the matching standard
trust levels, lower then your requirement and move the privileged operation to
a separate assembly which has full trust, and demand a custom permission to
identify the calling code and then assert the required privilege permission
before executing the privileged operation.
More Information
When should I put assemblies in GAC, what are
security implications?
You should put assemblies in GAC only when the assembly is
to be shared by several applications on the computer. Assemblies deployed in
the GAC must be strong named, as they are integrity checked at the time of
addition to GAC.
The security implications of assemblies added to GAC is that
the assemblies by default get full trust. Hence it becomes important to add
only trusted third party assemblies to GAC.
Assemblies put in GAC, to be accessed by partially trusted
code, needs to be marked with APTCA attribute. You need to be cautious while
marking assemblies with APTCA as any malicious code can access the assembly and
perform privileged operations. Hence before performing the privileged operation
the APTCA marked assemblies should demand custom or some specific permission
which allowed partial trust code will have.
Impersonation / Delegation
- When do I use impersonation in ASP.NET 2.0?
- How do I impersonate the original caller?
- How do I temporarily impersonate the original caller?
- How do I impersonate a specific (fixed) identity?
- When should I use programmatic impersonation?
- How do I use programmatic impersonation?
- What is protocol transition and when do I care?
- What is Constrained Delegation?
- How can I retain impersonatio