ASP.NET 中通过Form身份验证 来模拟Windows 域服务身份验证的方法

This step-by-step article demonstrates how an ASP.NET   application can use Forms authentication to permit users to authenticate   against the Active Directory by using the Lightweight Directory Access Protocol   (LDAP). After the user is authenticated and redirected, you can use the Application_AuthenticateRequest method of the Global.asax file to store a GenericPrincipal object in the HttpContext.User property that flows throughout the request.

Create an ASP.NET Web application in Visual C# .NET

Follow these steps to create a new ASP.NET Web application named   FormsAuthAd in Visual C# .NET:

  1. Start Microsoft Visual Studio .NET.
  2. On the File menu, point to New, and then click Project.
  3. Click Visual C# Projects under Project Types, and then click ASP.NET Web Application under Templates.
  4. In the Location box, replace WebApplication1 with FormsAuthAd.
  5. Click OK.
  6. Right-click the References node in Solution Explorer, and then click Add Reference.
  7. On the .NET tab in the Add Reference dialog box, click System.DirectoryServices.dll, click Select, and then click OK.

Write the authentication code

Follow these steps to create a new class file named   LdapAuthentication.cs:

  1. In Solution Explorer, right-click the project node, point to Add, and then click Add New Item.
  2. Click Class under Templates.
  3. Type LdapAuthentication.cs in the Name box, and then click Open.
  4. Replace the existing code in the LdapAuthentication.cs file with the following code.
 1 using System;
 2 using System.Text;
 3 using System.Collections;
 4 using System.DirectoryServices;
 5
 6 namespace FormsAuth
 7 {
 8   public class LdapAuthentication
 9   {
10     private String _path;
11     private String _filterAttribute;
12
13     public LdapAuthentication(String path)
14     {
15       _path = path;
16     }
17
18     public bool IsAuthenticated(String domain, String username, String pwd)
19     {
20       String domainAndUsername = domain + @"\" + username;
21       DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);
22
23       try
24       {    //Bind to the native AdsObject to force authentication.
25          Object obj = entry.NativeObject;
26
27     DirectorySearcher search = new DirectorySearcher(entry);
28
29     search.Filter = "(SAMAccountName=" + username + ")";
30     search.PropertiesToLoad.Add("cn");
31     SearchResult result = search.FindOne();
32
33     if(null == result)
34     {
35         return false;
36     }
37
38     //Update the new path to the user in the directory.
39     _path = result.Path;
40     _filterAttribute = (String)result.Properties["cn"][0];
41       }
42       catch (Exception ex)
43       {
44         throw new Exception("Error authenticating user. " + ex.Message);
45       }
46
47     return true;
48      }
49
50      public String GetGroups()
51      {
52        DirectorySearcher search = new DirectorySearcher(_path);
53        search.Filter = "(cn=" + _filterAttribute + ")";
54        search.PropertiesToLoad.Add("memberOf");
55        StringBuilder groupNames = new StringBuilder();
56
57        try
58        {
59          SearchResult result = search.FindOne();
60
61      int propertyCount = result.Properties["memberOf"].Count;
62
63         String dn;
64      int equalsIndex, commaIndex;
65
66      for(int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
67      {
68        dn = (String)result.Properties["memberOf"][propertyCounter];
69
70            equalsIndex = dn.IndexOf("=", 1);
71        commaIndex = dn.IndexOf(",", 1);
72        if(-1 == equalsIndex)
73        {
74          return null;
75             }
76
77            groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
78        groupNames.Append("|");
79
80          }
81        }
82        catch(Exception ex)
83        {
84          throw new Exception("Error obtaining group names. " + ex.Message);
85        }
86        return groupNames.ToString();
87      }
88    }
89 }

The authentication code accepts a domain, a user name, a   password, and a path to the tree in the Active Directory. This code uses the   LDAP directory provider.

The code in the Logon.aspx page calls the LdapAuthentication.IsAuthenticated method and passes in the credentials that are collected from the   user. Then, a DirectoryEntry object is created with the path to the directory tree, the user   name, and the password. The user name must be in the "domain\username" format.   The DirectoryEntry object then tries to force the AdsObject binding by obtaining the NativeObject property. If this succeeds, the CN attribute for the user is obtained by creating a DirectorySearcher object and by filtering on the SAMAccountName. After the user is authenticated, the IsAuthenticated method returns true.

To obtain a list of groups that the user belongs to,   this code calls the LdapAuthentication.GetGroups method. The LdapAuthentication.GetGroups method obtains a list of security and distribution groups that   the user belongs to by creating a DirectorySearcher object and by filtering according to the memberOf attribute. This method returns a list of groups that is separated   by pipes (|).

Notice that the LdapAuthentication.GetGroups method manipulates and truncates strings. This reduces the length   of the string that is stored in the authentication cookie. If the string is not   truncated, the format of each group appears as follows.

CN=...,...,DC=domain,DC=com

This can create a very long string. If the length of this string is   greater than the length of the cookie, browsers may not accept the authentication cookie, and you will be redirected to the logon page. However,   if you are in a multi-domain environment, you may have to keep the domain name    with the group name because groups in different domains can have the   same group name. You have to keep the domain name to differentiate one group   from another.
Most browsers support cookies of up to 4096 bytes. If this string may potentially   exceed the length of the cookie,   you may want to store the group information in the ASP.NET Cache object or in a   database. Alternatively, you may want to encrypt the group information and   store this information in a hidden form field.

Write the Global.asax code

The code in the Global.asax file provides an Application_AuthenticateRequest event handler. This event handler retrieves the authentication   cookie from the Context.Request.Cookies collection, decrypts the cookie, and retrieves the list of groups   that will be stored in the FormsAuthenticationTicket.UserData property. The groups appear in a pipe-separated list that is   created in the Logon.aspx page.
The code parses the string in a   string array to create a GenericPrincipal object. After the GenericPrincipal object is created, this object is placed in the HttpContext.User property.

  • In Solution Explorer, right-click Global.asax, and then click .
  • Add the following code at the top of the code-behind Global.asax.cs file:
1 using System.Web.Security;
2 using System.Security.Principal;
  • Replace the existing empty event handler for the Application_AuthenticateRequest with the following code.
 1 void Application_AuthenticateRequest(Object sender, EventArgs e)
 2 {
 3   String cookieName = FormsAuthentication.FormsCookieName;
 4   HttpCookie authCookie = Context.Request.Cookies[cookieName];
 5
 6   if(null == authCookie)
 7   {//There is no authentication cookie.
 8     return;
 9   }
10
11   FormsAuthenticationTicket authTicket = null;
12
13   try
14   {
15     authTicket = FormsAuthentication.Decrypt(authCookie.Value);
16   }
17   catch(Exception ex)
18   {
19     //Write the exception to the Event Log.
20     return;
21   }
22
23   if(null == authTicket)
24   {//Cookie failed to decrypt.
25     return;
26   }
27
28   //When the ticket was created, the UserData property was assigned a
29   //pipe-delimited string of group names.
30   String[] groups = authTicket.UserData.Split(new char[]{‘|‘});
31
32   //Create an Identity.
33   GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
34
35   //This principal flows throughout the request.
36   GenericPrincipal principal = new GenericPrincipal(id, groups);
37
38   Context.User = principal;
39
40 }

Modify the Web.config file

In this section, you configure the <forms>, the <authentication>, and the <authorization> elements in the Web.config file. With these changes, only   authenticated users can access the application, and unauthenticated requests   are redirected to a Logon.aspx page. You can modify this configuration to   permit only certain users and groups access to the application.

Replace the existing code in the Web.config file with the following code.

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <system.web>
 4     <authentication mode="Forms">
 5       <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" >
 6       </forms>
 7     </authentication>
 8     <authorization>
 9       <deny users="?" />
10       <allow users="*" />
11     </authorization>
12     <identity impersonate="true" />
13   </system.web>
14 </configuration>
15             

Notice the <identity impersonate="true" /> configuration element. This causes ASP.NET to impersonate the account that is configured as the anonymous account from Microsoft Internet Information Services (IIS). As a result of this configuration, all requests to this application run under the security context of the configured account. The user provides credentials to authenticate against the Active Directory, but the account that accesses the Active Directory is the configured account. For more information, see the References section.

Configure IIS for anonymous authentication

To configure IIS for anonymous authentication, follow these steps:

  • 在要做配置的站点中双击身份认证
  • 启用匿名身份验证
  • 使应用程序的匿名帐户成为对 Active Directory 域服务具有权限的帐户。

Create the Logon.aspx page

Follow these steps to create a new ASP.NET Web Form named   Logon.aspx:

In Solution Explorer, right-click the project node, point to Add, and then click Add Web Form.

  • Type Logon.aspx in the Name box, and then click Open.
  • In Solution Explorer, right-click Logon.aspx, and then click View Designer.
  • Click the HTML tab in the Designer.
  • Replace the existing code with the following code.
 1 <%@ Page language="c#" AutoEventWireup="true" %>
 2 <%@ Import Namespace="FormsAuth" %>
 3 <html>
 4   <body>
 5     <form id="Login" method="post" runat="server">
 6       <asp:Label ID="Label1" Runat=server >Domain:</asp:Label>
 7       <asp:TextBox ID="txtDomain" Runat=server ></asp:TextBox><br>
 8       <asp:Label ID="Label2" Runat=server >Username:</asp:Label>
 9       <asp:TextBox ID=txtUsername Runat=server ></asp:TextBox><br>
10       <asp:Label ID="Label3" Runat=server >Password:</asp:Label>
11       <asp:TextBox ID="txtPassword" Runat=server TextMode=Password></asp:TextBox><br>
12       <asp:Button ID="btnLogin" Runat=server Text="Login" OnClick="Login_Click"></asp:Button><br>
13       <asp:Label ID="errorLabel" Runat=server ForeColor=#ff3300></asp:Label><br>
14       <asp:CheckBox ID=chkPersist Runat=server Text="Persist Cookie" />
15     </form>
16   </body>
17 </html>
18 <script runat=server>
19 void Login_Click(Object sender, EventArgs e)
20 {
21   String adPath = "LDAP://corp.com"; //Fully-qualified Domain Name
22   LdapAuthentication adAuth = new LdapAuthentication(adPath);
23   try
24   {
25     if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
26     {
27       String groups = adAuth.GetGroups();
28
29       //Create the ticket, and add the groups.
30       bool isCookiePersistent = chkPersist.Checked;
31       FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,  txtUsername.Text,
32     DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);
33
34       //Encrypt the ticket.
35       String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
36
37       //Create a cookie, and then add the encrypted ticket to the cookie as data.
38       HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
39
40       if(true == isCookiePersistent)
41     authCookie.Expires = authTicket.Expiration;
42
43       //Add the cookie to the outgoing cookies collection.
44       Response.Cookies.Add(authCookie);
45
46       //You can redirect now.
47       Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
48     }
49     else
50     {
51       errorLabel.Text = "Authentication did not succeed. Check user name and password.";
52     }
53   }
54   catch(Exception ex)
55   {
56     errorLabel.Text = "Error authenticating. " + ex.Message;
57   }
58 }
59 </script>
  • Modify the path in the Logon.aspx page to point to your LDAP Directory server.

The Logon.aspx page is a page that collects the information   from the user and call methods on the LdapAuthentication class. After the code authenticates the user and obtains a list   of groups, the code creates a FormsAuthenticationTicket object, encrypts the ticket, adds the encrypted ticket to a   cookie, adds the cookie to the HttpResponse.Cookies collection, and then redirects the request to the URL that was   originally requested.

Modify the WebForm1.aspx page

The WebForm1.aspx page is the page that is requested originally.   When the user requests this page, the request is redirected to the Logon.aspx   page. After the request is authenticated, the request is redirected to the   WebForm1.aspx page.

  • In Solution Explorer, right-click WebForm1.aspx, and then click View Designer.
  • Click the HTML tab in the Designer.
  • Replace the existing code with the following code.
 1 <%@ Page language="c#" AutoEventWireup="true" %>
 2 <%@ Import Namespace="System.Security.Principal" %>
 3 <html>
 4   <body>
 5     <form id="Form1" method="post" runat="server">
 6       <asp:Label ID="lblName" Runat=server /><br>
 7       <asp:Label ID="lblAuthType" Runat=server />
 8     </form>
 9   </body>
10 </html>
11 <script runat=server>
12 void Page_Load(Object sender, EventArgs e)
13 {
14   lblName.Text = "Hello " + Context.User.Identity.Name + ".";
15   lblAuthType.Text = "You were authenticated using " +   Context.User.Identity.AuthenticationType + ".";
16 }
17 </script>
18         
  • Save all files, and then compile the project.
  • Request the WebForm1.aspx page. Notice that you are redirected to Logon.aspx.
  • Type the logon credentials, and then click Submit. When you are redirected to WebForm1.aspx, notice that your user name appears and that LdapAuthentication is the authentication type for the Context.User.AuthenticationType property.

Note: Microsoft recommends that you use Secure Sockets Layer (SSL)   encryption when you use Forms authentication. This is because the user is   identified based on the authentication cookie, and SSL encryption on this   application prevents anyone from compromising the authentication cookie and any   other valuable information that is being transmitted.

时间: 2024-12-19 13:25:27

ASP.NET 中通过Form身份验证 来模拟Windows 域服务身份验证的方法的相关文章

asp.net中通过form表单submit提交到后台的实例

前台<body>中的代码: <body> <div id="top"> </div> <form id="login" name="login" action="?Action=Login" method="post"> <div id="center"> <div id="center_left&q

asp.net5中使用NLog进行日志记录

asp.net5中提供了性能强大的日志框架,本身也提供了几种日志记录方法,比如记录到控制台或者事件中等,但是,对大部分程序员来说,更喜欢使用类似log4net或者Nlog这种日志记录方式,灵活而强大.asp.net5中也包括NLog的实现,下面把最简单的使用方法写出来,抛砖引玉,让更多对此不熟悉的同学们能借此入门. 1.在project.json中添加对Microsoft.Framework.Logging.NLog的引用,目前最新是beta8版本: 2.然后添加NLog.config配置文件到

[转]asp.net5中使用NLog进行日志记录

本文转自:http://www.cnblogs.com/sguozeng/articles/4861303.html asp.net5中使用NLog进行日志记录 asp.net5中提供了性能强大的日志框架,本身也提供了几种日志记录方法,比如记录到控制台或者事件中等,但是,对大部分程序员来说,更喜欢使用类似log4net或者Nlog这种日志记录方式,灵活而强大.asp.net5中也包括NLog的实现,下面把最简单的使用方法写出来,抛砖引玉,让更多对此不熟悉的同学们能借此入门. 1.在project

ASP.NET中身份验证的三种方法

Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活.Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端.服务端上的授权设置就可以根据不同目录对不同用户的访问授权进行控制了. 问题来了,在实际是用中我们往往需要的是基于角色,或者说基于用户组的验

ASP.NET中身份验证

ASP.NET中身份验证有三种方式:Windows.Forms和Passport. 1.Windows验证,基于窗体验证,需要每个页面写上验证身份代码,相对灵活,但操作过于复杂: 2.Passport验证,使用由微软提供的集中身份验证方式,安全性较高,但实现较复杂: 3.Forms验证,将所定义的文件和目录集中到一个页面去做验证,将用户的身份发回写到客户端的Cookie,在Cookie未过期的时间段内用户再次访问网站,就会连同身份Cookie发送到服务器端,服务端的授权设置可以根据不同目录不同用

ASP.NET4中不要相信Request.Browser.Cookies,Form验证要用UseCookies

从ASP.NET 3.5升级至ASP.NET4之后,遇到三种登录后不能保存cookie的情况(升级前一切正常): 1. 遨游3在极速模式下(默认模式). 2. FireFox中修改了UserAgent. 3. 诺基亚手机自带浏览器或者UCWeb浏览器访问博客园手机版(m.cnblogs.com). 今天终于把罪魁祸首给揪出来了,它就是Request.Browser.Cookies. 如果你在程序中使用Form验证并使用cookie保存用户的登录状态,请切记:在<authentication mo

ASP.NET中的身份验证有那些?你当前项目采用什么方式验证请解释

ASP.NET身份验证模式包括Windows.Forms(窗体).Passport(护照)和None(无). l  Windows身份验证—常结合应用程序自定义身份验证使用使用这种身份验证模式时,ASP.NET依赖于IIS对用户进行验证,并创建一个Windows访问令牌来表示已通过验证的标识.IIS提供以下几种身份验证机制: l  Passport身份验证.使用这种身份验证模式时,ASP.NET使用Microsoft Passport的集中式身份验证服务,该服务为成员站点提供单一登录和核心配置文

asp.net中使用基于角色role的Forms验证

http://www.cnblogs.com/yao/archive/2006/06/24/434783.html asp.net中使用基于角色role的Forms验证,大致经过几下四步:1.配置系统web.config system.web> <authentication mode="Forms" >  <forms name=".yaoCookies" loginUrl="/duan/Manage/login.aspx&quo

在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证

注:下载本文提到的完整代码示例请访问:How to authorization Angular 2 app with asp.net core web api 在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证 Angular2是对Angular1的一次彻底的,破坏性的更新. 相对于Angular1.x,借用某果的广告语,唯一的不同,就是处处都不同. 首先,推荐的语言已经不再是Javascript,取而代之的TypeScript,(TypeSc