With
Windows authentication, the web server takes care of the authentication
process. ASP.NET simply makes this identity available to your code for
your security checks.
When you use
Windows authentication, you force users to log into IIS before they're
allowed to access secure content in your website. The user login
information can be transmitted in several ways (depending on the
network environment, the requesting browser, and the way IIS is
configured), but the end result is that the user is authenticated using
a local Windows account. Typically, this makes Windows authentication
best suited to intranet scenarios, in which a limited set of known
users is already registered on a network server.
To implement Windows-based security with known users, you need to follow three steps:
Set
the authentication mode to Windows authentication in the web.config
file. (If you prefer a graphical tool, you can use the WAT during
development or IIS Manager after deployment.)
Disable anonymous access for a directory by using an authorization rule.
Configure the Windows user accounts on your web server (if they aren't already present).
You'll walk through these steps in the following sections.
NOTE
The built-in Visual
Studio web server doesn't support anonymous users with Windows
authentication. Instead, Visual Studio automatically logs you in to the
test server using your Windows account. As a result, there's no need to
use an authorization rule that denies anonymous users. However, it's
still good practice to add it, because at some point you will deploy
your application to IIS and need to explicitly deny anonymous users.
1. Web.config Settings
To use Windows authentication,
you need to make sure the <authentication> element is set
accordingly in your web.config file. Here's how:
<configuration>
<system.web>
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
...
</system.web>
</configuration>
At the moment, there's
only one authorization rule, which uses the question mark to refuse all
anonymous users. This step is critical for Windows authentication (as
it is for forms authentication). Without this step, the user will never
be forced to log in.
Ideally, you won't even see
the login process take place. Instead, Internet Explorer will pass
along the credentials of the current Windows user, which the web server
uses automatically. The Visual Studio integrated web server always
works this way. IIS also works this way, provided you've set up
integrated Windows authentication and the browser supports it.
You can also add <allow>
and <deny> elements to specifically allow or restrict users from
specific files or directories. Unlike with forms authentication, you
need to specify the name of the server or domain where the account
exists. For example, this rule allows the user account matthew, which
is defined on the computer named WebServer:
<allow users="WebServer\matthew" />
For a shortcut, you can use localhost (or just a period) to refer to an account on the current computer, as shown here:
<allow users=".\matthew" />
You can also restrict
certain types of users, provided their accounts are members of the same
Windows group, by using the roles attribute:
<authorization>
<deny users="?" />
<allow roles=".\SalesAdministrator,.\SalesStaff" />
<deny users=".\matthew" />
</authorization>
In this
example, all users who are members of the SalesAdministrator or
SalesStaff groups will be automatically authorized to access ASP.NET
pages in this directory. Requests from the user matthew will be denied,
unless he is a member of the SalesAdministrator or SalesStaff group.
Remember, ASP.NET examines rules in the order they appear and stops
when it finds a match. Reversing these two authorization lines would
ensure that the user matthew was always denied, regardless of group
membership.
You can also examine a user's group membership programmatically in your code, as shown here.
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
If User.IsInRole("MyDomainName\SalesAdministrators") Then
' Do nothing; the page should be accessed as normal because
' the user has administrator privileges.
Else
' Don't allow this page. Instead, redirect to the home page.
Response.Redirect("Default.aspx")
End If
End Sub
In this example, the code
checks for membership in a custom Windows group called
SalesAdministrators. If you want to check whether a user is a member of
one of the built-in groups, you don't need to specify a computer or
domain name. Instead, you use this syntax:
If User.IsInRole("BUILTIN\Administrators") Then
' (Code goes here.)
End If
Note that you have no way
to retrieve a list of available groups on the web server (that would
violate security), but you can find out the names of the default
built-in Windows roles using the
System.Security.Principal.WindowsBuiltInRole enumeration. Table 1 describes these roles. Not all will apply to ASP.NET use, although Administrator, Guest, and User probably will.
Table 1. Default Windows Roles
Role | Description |
---|
AccountOperator | Users with the special responsibility of managing the user accounts on a computer or domain. |
Administrator | Users
with complete and unrestricted access to the computer or domain. (If
the web server computer uses user account control [UAC], Windows will
hold back administrator privileges from administrator accounts, to
reduce the risk of viruses and other malicious code.) |
BackupOperator | Users who can override certain security restrictions only as part of backing up or restore operations. |
Guest | Like the User role but even more restrictive. |
PowerUser | Similar to Administrator but with some restrictions. |
PrintOperator | Like User but with additional privileges for taking control of a printer. |
Replicator | Like User but with additional privileges to support file replication in a domain. |
SystemOperator | Similar to Administrator with some restrictions. Generally, system operators manage a computer. |
User | Users are prevented from making systemwide changes and can run only certified applications (see http://www.microsoft.com/windowsserver2008/en/us/isv.aspx for more information). |
2. A Windows Authentication Test
One of the nice
features of Windows authentication is that no login page is required.
Depending on the authentication protocol you're using , the login process may take place
automatically or the browser may show a login dialog box. Either way,
you don't need to perform any additional work.
You can retrieve
information about the currently logged-on user from the User object. As
you learned earlier, the User object provides identity information
through the User.Identity property. Depending on the type of
authentication, a different identity object is used, and each identity
object can provide customized information. To get some additional
information about the identity of the user who has logged in with
Windows authentication, you can convert the generic IIdentity object to
a WindowsIdentity object (which is defined in the
System.Security.Principal namespace).
The following is a sample test page that uses Windows authentication (see Figure 1).
To use this code as written, you need to import the
System.Security.Principal namespace (where the WindowsIdentity class is
defined).
Public Partial Class SecuredPage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Dim displayText As New StringBuilder()
displayText.Append("You have reached the secured page, ")
displayText.Append(User.Identity.Name)
Dim winIdentity As WindowsIdentity
winIdentity = CType(User.Identity, WindowsIdentity)
displayText.Append(".<br /><br />Authentication Type: ")
displayText.Append(winIdentity.AuthenticationType)
displayText.Append("<br />Anonymous: ")
displayText.Append(winIdentity.IsAnonymous)
displayText.Append("<br />Authenticated: ")
displayText.Append(winIdentity.IsAuthenticated)
displayText.Append("<br />Guest: ")
displayText.Append(winIdentity.IsGuest)
displayText.Append("<br />System: ")
displayText.Append(winIdentity.IsSystem)
displayText.Append("<br />Administrator: ")
displayText.Append(User.IsInRole("BUILTIN\Administrators"))
lblMessage.Text = displayText.ToString()
End Sub
End Class