About ASP-Windows identity authentication

Source: Internet
Author: User
Tags findone ldap ldap protocol net thread samaccountname

Last blog I talked about the topic of ASP. NET Forms authentication, this time the blog will mainly introduce the ASP. NET Windows Authentication.

Although forms authentication is widely used, it is also convenient to use Windows authentication if you are using ASP. NET in the context of Windows Active Directory. Ease of use: we don't have to design login pages, we don't have to write login verification logic. and using Windows identity authentication can be a better security.

Get back to the top learn about ASP. NET Windows identity authentication

To use Windows Authentication mode, you need to set the Web. config:

<authentication mode= "Windows"/>

Windows authentication is the default authentication method for ASP., and forms authentication is the same in many basic ways. I said in my previous blog: " I think the core of the identity authentication of ASP is actually the object that httpcontext.user this attribute points to." in the next section, I'll focus on how this object differs from the two types of identity authentication.

The two interfaces of IPrincipal and IIdentity play an important role in the process of ASP. The former defines the basic functions of the user object, the latter defines the basic functions of the identity object, and the different authentication methods of the two interface instances are different.

ASP. NET Windows Authentication is implemented by WindowsAuthenticationModule. WindowsAuthenticationModule using the Windows access token (token) passed from IIS to ASP in the AuthenticateRequest event of the ASP. Create a WindowsIdentity object, token is obtained by calling Context.WorkerRequest.GetUserToken (), and then based on the WindowsIdentity object to create the WindowsPrincipal object and assign it to HttpContext.User.

In forms authentication, we need to create a login page, let the user submit a user name and password, and then check the correctness of the user name and password, and then create a login cookie containing the FormsAuthenticationTicket object for subsequent requests to use. formsauthenticationmodule resolves the login cookie and creates a GenericPrincipal object that contains formsidentity in the AuthenticateRequest event of the ASP. and assign it to HttpContext.User.

The above two paragraphs simply summarize the way of working with two kinds of authentication methods.
We can see that they differ in the following:
1. Forms authentication requires a cookie to indicate login status, and Windows authentication relies on IIS
2. Windows authentication does not require us to design a login page, so it is easier to use without writing login verification logic.

During the authorization phase, UrlAuthorizationModule still checks whether the resource to be accessed is licensed based on the current user. Next, FileAuthorizationModule checks if the IIdentity object in the HttpContext.User.Identity property is an instance of the WindowsIdentity class. If the IIdentity object is not an instance of the WindowsIdentity class, the FileAuthorizationModule class stops processing. If an instance of the WindowsIdentity class exists, the FileAuthorizationModule class calls the AccessCheck Win32 function (via P/invoke) to determine whether the authenticated client is authorized to access the requested file. If there is at least one Read access control entry (ACE) in the Discretionary Access Control List (DACL) of the file's security descriptor, the request is allowed to continue. Otherwise, the FileAuthorizationModule class calls the Httpapplication.completerequest method and returns the status code 401 to the client.

In Windows identity authentication, the verification work is primarily implemented by IIS, and WindowsAuthenticationModule is actually responsible for creating WindowsPrincipal and WindowsIdentity. By the way: Windows Authentication is also divided into "NTLM Authentication" and "Kerberos v5 authentication" Two, more instructions on these two Windows authentication can be viewed in the MSDN technical article: Explanation: Windows Authentication in ASP. In my opinion, the type of Windows authentication that IIS eventually uses does not affect our development process, so this article will not discuss this topic.

In my practical experience, when using Windows Authentication, the main development effort will be to obtain user information from Active Directory based on the login name. Because, we do not need to design the login process at this time, IIS and ASP. WindowsPrincipal and WindowsIdentity are ready for the two user identity related objects.

Back to top access Active Directory

We typically use the LDAP protocol to access active Directory, and the two types of DirectoryEntry and DirectorySearcher are available in the. NET Framework, allowing us to easily access the active from managed code Directory Domain Services.

If we were to search for a user's information in the "Test.corp" field, we could construct a DirectoryEntry object using the following statement:

DirectoryEntry entry = new DirectoryEntry ("Ldap://test.corp");

In this code, I used a hard-coded way to write the domain name into the code.
How do we know which domain name is being used by the current computer?
The answer is: View the Properties dialog box for my computer:

Note: This domain name is not necessarily the same as System.Environment.UserDomainName.

In addition to viewing the Properties dialog box for my computer, we can also use the code to get the domain name used by the current computer:

private static string Getdomainname () {    //NOTE: This code needs to work in Windows XP and the newer version of the operating system.    selectquery query = new SelectQuery ("Win32_ComputerSystem");    using (ManagementObjectSearcher searcher = new ManagementObjectSearcher (query)) {        foreach (managementobject mo in SE Archer. Get ()) {            if ((bool) mo["Partofdomain"])                return mo["domain"]. ToString ();        }    }    return null;}

Once the DirectorySearcher object has been constructed, we can use DirectorySearcher to perform a search of Active Directory.
We can use the following steps to perform a search:
1. Set Directorysearcher.filter to indicate the LDAP format filter, which is a string.
2. Call Propertiestoload.add () multiple times to set the list of properties to retrieve during the search.
3. Call the FindOne () method to get the search results.

The following code shows how to search for user information from Active Directory with the login name "Fl45":

static void Main (string[] args) {Console.WriteLine (environment.userdomainname);    Console.WriteLine (Environment.username);    Console.WriteLine ("------------------------------------------------"); Showuserinfo ("Fl45", Getdomainname ());} private static string allproperties = "Name,givenname,samaccountname,mail";p ublic static void Showuserinfo (string LoginName, String domainName) {if (string. IsNullOrEmpty (loginName) | | String.    IsNullOrEmpty (DomainName)) return; String[] Properties = Allproperties.split (new char[] {' \ r ', ' \ n ', ', '}, Stringsplitoptions.remov    Eemptyentries);        try {DirectoryEntry entry = new DirectoryEntry ("LDAP://" + domainName);        DirectorySearcher search = new DirectorySearcher (entry); Search.        Filter = "(samaccountname=" + LoginName + ")"; foreach (String p in properties) search.        Propertiestoload.add (P); SearchResult result = search.        FindOne ();           if (result! = null) { foreach (String p in properties) {resultpropertyvaluecollection collection = result.                PROPERTIES[P]; for (int i = 0; i < collection. Count;            i++) Console.WriteLine (P + ":" + collection[i]); }}} catch (Exception ex) {Console.WriteLine (ex).    ToString ()); }}

The results are as follows:

In the previous code, when I searched Active Directory, I searched only for "Name,givenname,samaccountname,mail" 4 properties. However, LDAP also supports more attributes, and we can use the following code to see more user information:

Back to top access active Directory in ASP.

In front of me, I demonstrated the way to access Active Directory in a console program, and with an example we can see that in code, I use Environment.username to get the current user's login name. However, if you are in an ASP. NET program, access to Environment.username is likely to not get a real user login name. Because: Environment.username is using GetUserName in Win32API to get the thread-related user name, but ASP. NET is running in IIS, the thread-related user name is not necessarily the client's user name. However, ASP. NET can simulate the way users run, in this way can get the correct results. The topic of "simulation" is described later in this article.

In ASP., we can use the following code in order to reliably obtain the login name of the logged-on user:

<summary>///Gets the login name based on the specified HttpContext object. </summary>///<param name= "context" ></param>///<returns></returns>public static String Getuserloginname (HttpContext context) {    if (context = = null)        return null;    if (context. Request.isauthenticated = = false)        return null;    String userName = context. User.Identity.Name;    At this point the format of username is: userdomainname\loginname    //We just need the LoginName on the back.    string[] Array = username.split (new char[] {' \ \ '}, stringsplitoptions.removeemptyentries);    if (array. Length = = 2)        return array[1];    return null;}

When using Windows identity Authentication in ASP. IIS and WindowsAuthenticationModule have done a lot of work on verifying users, although we can use the preceding code to get the user's login name, But the user's other information needs our own to obtain. What we do when we actually use Windows authentication is basically getting all the information we need from Active Directory based on the user's login name.

For example, when my program is running, I also need to use the following user-related information:

public sealed class userinfo{public    string GivenName;    public string FullName;    public string Email;}

So, we can use this code to get the required user information:

Use Userhelper's page code:

The effect of the program operation is as follows:

In addition, you can query a property called memberof from Active Directory (which is independent of the Windows user group), and sometimes you can use it to differentiate between users and to design permissions-related actions.

When designing the table structure of data persistence, because there is no "user table" at this time, we can save the user's login name directly. The rest of the development work is not much different from forms authentication.

Back to top use Active Directory to authenticate users

In this way, IIS and WindowsAuthenticationModule have implemented the user authentication process as described in the previous ASP. However, there may be times when we need to programmatically use Active Directory to authenticate user identities, such as in WinForm programs, or other validation logic, for a variety of reasons.

Not only can we query the user information from Active Directory, we can also use it to authenticate the user, so that we can implement our own login verification logic.

Regardless of how active Directory is used, we need to use the two objects DirectoryEntry and DirectorySearcher. DirectoryEntry also provides a constructor that allows us to enter a user name and password:

Abstract://     Initializes a new instance of the System.DirectoryServices.DirectoryEntry class. Parameter://   password://the     password to use when authenticating the client. The Directoryentry.password property is initialized to this value.   username://The     user name to use when authenticating the client. The Directoryentry.username property is initialized to this value.   path://The     path to this DirectoryEntry. The Directoryentry.path property is initialized to this value. Public DirectoryEntry (string path, string Username, string password);

To implement your own login checks, you need to use this constructor.
Here is an example of a login check I wrote with WinForm:

private void Btnlogin_click (object sender, EventArgs e) {    if (txtUsername.Text.Length = = 0 | | txtPassword.Text.Length = = 0) {        MessageBox.Show ("username or password cannot be empty.) ", this. Text, MessageBoxButtons.OK, messageboxicon.warning);        return;    }    String Ldappath = "ldap://" + getdomainname ();    String domainandusername = environment.userdomainname + "\ \" + txtUsername.Text;    DirectoryEntry entry = new DirectoryEntry (Ldappath, Domainandusername, txtpassword.text);    DirectorySearcher search = new DirectorySearcher (entry);    try {        SearchResult result = search. FindOne ();        MessageBox.Show ("Login successful. ", this. Text, MessageBoxButtons.OK, messageboxicon.information);    }    catch (Exception ex) {        //If the user name or password is incorrect, an exception is thrown.        MessageBox.Show (ex. Message, this. Text, MessageBoxButtons.OK, messageboxicon.stop);}    }

The effect of the program operation is as follows:

Back to top security context with user impersonation

In an ASP. NET Windows Authentication environment, the user-related security context object is stored in the HttpContext.User property, which is an object of type WindowsPrincipal. We can also access the HttpContext.User.Identity to obtain an authenticated user ID, which is an object of type WindowsIdentity.

In the. NET framework, we can get the WindowsIdentity object associated with the current thread through WindowsIdentity.GetCurrent (), which gets the security context identity of the currently running WIN32 thread. Because ASP. NET is running in the IIS process, the security identity of the ASP. NET thread is actually inherited from the IIS process, so the WindowsIdentity objects obtained in two ways are actually different.

In the Windows operating system, many permission checks are based on the WIN32 thread's security context identity, so the previous two WindowsIdentity objects will cause inconsistencies in the programming model, in order to solve this problem, ASP. NET provides "impersonation" functionality that allows threads to access resources in the security context of a particular Windows account.

In order to better understand the function of simulation, I prepared an example (SHOWWINDOWSIDENTITY.ASHX):

public class Showwindowsidentity:ihttphandler {public void ProcessRequest (HttpContext context) {//To observe " Impersonation "effects,//Can be enabled, prohibit settings in Web. config: <identity impersonate=" true "/> Context.        Response.ContentType = "Text/plain"; Context.                Response.Write (environment.userdomainname + "\" + environment.username + "\ r \ n");        WindowsPrincipal Winprincipal = (WindowsPrincipal) HttpContext.Current.User; Context. Response.Write (String. Format ("HttpContext.Current.User.Identity: {0}, {1}\r\n", WinPrincipal.Identity.AuthenticationType, Winpri Ncipal.                Identity.name));        WindowsPrincipal WinPrincipal2 = (WindowsPrincipal) Thread.CurrentPrincipal; Context. Response.Write (String. Format ("Thread.CurrentPrincipal.Identity: {0}, {1}\r\n", WinPrincipal2.Identity.AuthenticationType, Winprin Cipal2.        Identity.name));        WindowsIdentity winId = WindowsIdentity.GetCurrent (); Context. Response.Write (StriNg.    Format ("WindowsIdentity.GetCurrent (): {0}, {1}", Winid.authenticationtype, Winid.name)); }

First, set in Web. config:

<authentication mode= "Windows"/>

Note: To deploy the Web site in IIS, you will not see the effect.

At this point, accessing Showwindowsidentity.ashx, you will see the results as shown:

Now modify the settings in Web. config: ( Note: The following adds a sentence configuration )

<authentication mode= "Windows"/><identity impersonate= "true"/>

At this point, accessing Showwindowsidentity.ashx, you will see the results as shown:

1. fish-srv2003 is my computer name. It is in an environment that has no domain.
2. Fish-li is the login name of one of my Windows accounts.
3. The Web site is deployed in IIS6 and the process runs in the Network Service account.
4. When I open a webpage, the username I entered is Fish-li

The difference between the previous two images is actually the function of the "simulation" of ASP.

About the simulation, I want to say four points:
1. In ASP. NET, we should access the HttpContext.User.Identity to get the current user ID, then there is no problem (it can not be simulated at this time ), For example, this is how fileauthorizationmodule is handled.
2. Impersonation is only useful when an ASP. NET application accesses Windows system resources with the Security Check feature applied to Windows.
3. Forms authentication can also configure impersonation capabilities, but only one Windows account can be emulated.
4. In most cases, simulations are not required.

Back to top Configure Windows identity authentication in IIS

Unlike programs that use Forms authentication, programs that use Windows Identity authentication require additional configuration steps. This section will focus on configuring Windows identity authentication in IIS, and I will describe these configurations as examples of commonly used IIS6 and IIS7.5.

for IIS6 configuration please refer to:

for IIS7.5 configuration please refer to:

Note: Windows Authentication is required for installation, please refer to:

Back to top about the browser login dialog box problem

When we use a browser to access a website that uses Windows authentication, the browser pops up a dialog box (left IE, right safari):

At this point, we are asked to enter the login account for Windows and then submit it to IIS for authentication.

The first pop-up of this dialog box is normal: Because the program wants to verify the user's identity.
However, this dialog box appears again each time you close the browser next time you reopen the page, and it is not convenient at this point.
Although some browsers can remember the user name and password, but I found that Firefox,opera,chrome will still pop up this dialog box, waiting for us to click OK, only Safari will not disturb users to open the page directly. IE's "Remember my password" check box is completely a device, it will never remember the password!

So, all the browsers I've tried, only Safari is the most humane.
Although IE does not remember the password by default, it needs to be entered again every time.
However,IE can support not prompting the user to enter the login account and open the Web page directly, when IE will use the user's current Windows logon account to pass to IIS authentication authentication.

To have IE open a Windows authenticated Web site without prompting the logon dialog box, the following conditions must be met:
1. Windows Integrated authentication must be enabled in the Web site properties of IIS.
2. Both the client and the Web server must be within the same domain that is based on Microsoft Windows.
3. Internet Explorer must treat the requested URL as an Intranet (local).
4. The security settings for the Intranet zone of Internet Explorer must be set to automatically log on only in the intranet zone.
5. The user requesting the Web page must have appropriate file system (NTFS) permissions to access the Web page and all objects referenced in the Web page.
6. Users must log on to Windows with a domain account.

In these conditions, if the Web site is running in a Windows domain, other conditions should be easy to satisfy except that the 3rd may not be satisfied (4th is the default value). Therefore, to let ie not prompt for login account, as long as the 3rd to ensure that the satisfaction of the. The following picture shows how to complete this configuration:(Note: The configuration method is also suitable for domain name access cases)

In addition, in addition to setting up an intranet in IE, you can also use the computer name instead of the IP address or domain name when you visit the Web site, ie always considers it to be accessing the Web site within the intranet, and the Login dialog box does not pop up at this time.

Here, I would like to say three more words:
1. IE when integrated with Windows authentication, although the logon dialog box is not prompted, but does not indicate that it is not secure, it automatically passes the logon credentials.
2. This behavior can only be supported by IE. (Other browsers just remember passwords, which are actually different in implementation.) )
3. Integrated Windows authentication is also only suitable for use in an intranet environment.

Back to the top page in client code that accesses Windows identity authentication

In my previous blog, I demonstrated how to access restricted pages in a Web site that uses forms authentication by using the Cookiecontainer object to receive a service-terminated login cookie. However, in a Windows authenticated Web site, the authentication process occurs in IIS and does not use a cookie to save the logon state at all, but rather requires that the necessary authentication information be sent on request.

When using code as a client Access Web server, we still need to use the HttpWebRequest object. To enable HttpWebRequest to send the necessary authentication information when accessing IIS, the HttpWebRequest provides two properties to complete this function:

Gets or sets the authentication information for the request. Returns the result://contains the System.Net.ICredentials of the     authentication credentials associated with the request. The default is null. public override ICredentials Credentials {get; set;} Gets or sets a System.Boolean value that controls whether the default credentials are sent with the request. Returns the result://     True if default credentials are used, otherwise false. The default value is False. public override bool useDefaultCredentials {get; set;}

Here is the complete sample code I prepared (note the comments in the code) :

static void Main (string[] args) {try {//WindowsAuthWebSite1 This site is deployed in IIS,//Enable Windows Authentication mode, and prohibit anonymous user access.        Then modify the access address below.        HttpWebRequest request = (HttpWebRequest) webrequest.create ("http://localhost:33445/Default.aspx");        The following three lines of code enable any line to be enabled. Request.        useDefaultCredentials = true; Request.        Credentials = CredentialCache.DefaultCredentials; Request.        Credentials = credentialcache.defaultnetworkcredentials;        If the above three lines of code are all commented out, you will see 401 of the exception information. using (HttpWebResponse response = (HttpWebResponse) request. GetResponse ()) {using (StreamReader sr = new StreamReader (response. GetResponseStream ())) {Console.WriteLine (Sr.)            ReadToEnd ());        }}} catch (WebException Wex) {Console.WriteLine ("====================================="); Console.WriteLine ("An exception has occurred.        ");        Console.WriteLine ("====================================="); Console.WriteLine (Wex. MesSAGE); }}

In fact, the key part is to set usedefaultcredentials or credentials, the code of three methods are valid.
The difference between the three methods:
1. Credentials = CredentialCache.DefaultCredentials; Indicates that the current user's authentication credentials are brought on the sending request.
2. useDefaultCredentials = true; This method internally calls the previous method, so it is the same as the previous method.
3. Credentials = Credentialcache.defaultnetworkcredentials; is a new method that is referenced in. NET 2.0.

For more differences between DefaultCredentials and defaultnetworkcredentials, check out the form I've compiled:

Credentials Property Declaration type Instance type . NET supported versions
DefaultCredentials ICredentials Systemnetworkcredential Starting from 1.0
Defaultnetworkcredentials NetworkCredential Systemnetworkcredential Starting from 2.0

Three types of inheritance relationships:
1. NetworkCredential implements the ICredentials interface,
2. Systemnetworkcredential inherits from NetworkCredential.

Before I finish this blog, I think I should thank the new egg.
In the network environment of the new egg, I learned to use Windows identity authentication.
In addition to thanking, I also now especially Miss Fl45 this login name ...

Transferred from: http://www.cnblogs.com/fish-li/archive/2012/05/07/2486840.html

About ASP-Windows identity authentication

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.