フォーム認証と Visual Basic .NET を使用して Active Directory に対する認証を行う方法

文書翻訳 文書翻訳
文書番号: 326340 - 対象製品
すべて展開する | すべて折りたたむ

目次

概要

この資料では、ASP.NET アプリケーションでフォーム認証を使用して、ユーザーが LDAP (Lightweight Directory Access Protocol) を使用して Active Directory に対する認証を行えるようにする方法について、手順を追って説明します。

ユーザーが認証されてリダイレクトされた後は、Global.asax ファイルの Application_AuthenticateRequest メソッドを使用して、要求全体にわたって使用される GenericPrincipal オブジェクトを HttpContext.User プロパティに格納することができます。

Visual Basic .NET で ASP.NET Web アプリケーションを作成する

以下の手順を実行して、Visual Basic .NET で FormsAuthAd という名前の ASP.NET Web アプリケーションを新規に作成します。
  1. Microsoft Visual Studio .NET を起動します。
  2. [ファイル] メニューの [新規作成] をポイントして、[プロジェクト] をクリックします。
  3. [プロジェクトの種類] の [Visual Basic プロジェクト] をクリックして、[テンプレート] の [ASP.NET Web アプリケーション] をクリックします。
  4. [場所] ボックスに、http://<servername>/FormsAuthAd (ローカルのサーバーを使用する場合は、http://localhost/FormsAuthAd) と入力し、[OK] をクリックします。
  5. [ソリューション エクスプローラ] の [参照設定] ノードを右クリックし、[参照の追加] をクリックします。
  6. [参照の追加] ダイアログ ボックスの [.NET] タブで、[System.DirectoryServices.dll]、[選択] の順にクリックし、[OK] をクリックします。

認証のコードを記述する

次の手順を実行して、LdapAuthentication.vb という名前のクラス ファイルを新規に作成します。
  1. [ソリューション エクスプローラ] で、プロジェクトのノードを右クリックし、[追加] をポイントし、[新しい項目の追加] をクリックします。
  2. [テンプレート] の [クラス] をクリックします。
  3. [ファイル名] ボックスに、LdapAuthentication.vb と入力し、[開く] をクリックします。
  4. LdapAuthentication.vb ファイルの既存のコードを、次のコードで置き換えます。
    Imports System
    Imports System.Text
    Imports System.Collections
    Imports System.DirectoryServices
    
    Namespace FormsAuth
        Public Class LdapAuthentication
    
            Dim _path As String
            Dim _filterAttribute As String
    
            Public Sub New(ByVal path As String)
                _path = path
            End Sub
    
            Public Function IsAuthenticated(ByVal domain As String, ByVal username As String, ByVal pwd As String) As Boolean
    
                Dim domainAndUsername As String = domain & "\" & username
                Dim entry As DirectoryEntry = New DirectoryEntry(_path, domainAndUsername, pwd)
    
                Try
                    'Bind to the native AdsObject to force authentication.			
                    Dim obj As Object = entry.NativeObject
                    Dim search As DirectorySearcher = New DirectorySearcher(entry)
    
                    search.Filter = "(SAMAccountName=" & username & ")"
                    search.PropertiesToLoad.Add("cn")
                    Dim result As SearchResult = search.FindOne()
    
                    If (result Is Nothing) Then
                        Return False
                    End If
    
                    'Update the new path to the user in the directory.
                    _path = result.Path
                    _filterAttribute = CType(result.Properties("cn")(0), String)
    
                Catch ex As Exception
                    Throw New Exception("Error authenticating user. " & ex.Message)
                End Try
    
                Return True
            End Function
    
            Public Function GetGroups() As String
                Dim search As DirectorySearcher = New DirectorySearcher(_path)
                search.Filter = "(cn=" & _filterAttribute & ")"
                search.PropertiesToLoad.Add("memberOf")
                Dim groupNames As StringBuilder = New StringBuilder()
    
                Try
                    Dim result As SearchResult = search.FindOne()
                    Dim propertyCount As Integer = result.Properties("memberOf").Count
    
                    Dim dn As String
                    Dim equalsIndex, commaIndex
    
                    Dim propertyCounter As Integer
    
                    For propertyCounter = 0 To propertyCount - 1
                        dn = CType(result.Properties("memberOf")(propertyCounter), String)
    
                        equalsIndex = dn.IndexOf("=", 1)
                        commaIndex = dn.IndexOf(",", 1)
                        If (equalsIndex = -1) Then
                            Return Nothing
                        End If
    
                        groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1))
                        groupNames.Append("|")
                    Next
    
                Catch ex As Exception
                    Throw New Exception("Error obtaining group names. " & ex.Message)
                End Try
    
                Return groupNames.ToString()
            End Function
        End Class
    End Namespace
    
    
    					

コードの説明

認証コードは、ドメイン、ユーザー名、パスワード、および Active Directory ツリーへのパスを受け取ります。このコードでは、LDAP ディレクトリ プロバイダを使用します。
ユーザー認証
Logon.aspx ページのコードは、LdapAuthentication.IsAuthenticated メソッドを呼び出し、ユーザーから収集した資格情報を渡します。次に、ディレクトリ ツリーへのパス、ユーザー名、パスワードを使用して、DirectoryEntry オブジェクトが作成されます。ユーザー名は、"domain\username" の形式になっている必要があります。DirectoryEntry オブジェクトでは、NativeObject プロパティを取得することによって強制的に AdsObject のバインドを試行します。バインドが正常に実行された場合、DirectorySearcher オブジェクトを作成し、SAMAccountName によるフィルタリングを行って、ユーザーの CN 属性を取得します。ユーザーが認証されると、IsAuthenticated メソッドは true を返します。

: LDAP を使用して Active Directory 関連のオブジェクトにバインドする場合、TCP ポートが使用されます。System.DirectoryServices 名前空間で LDAP の使用が増加すると、利用可能なすべての TCP ポートが使用される場合があります。ユーザーの認証に使用した接続を再利用することで、TCP の負荷を低減できる場合があります。
ユーザー グループ
ユーザーが所属するグループの一覧を取得するため、このコードでは LdapAuthentication.GetGroups メソッドを呼び出します。LdapAuthentication.GetGroups メソッドは、DirectorySearcher オブジェクトを作成し、memberOf 属性に従ってフィルタリングを行うことで、そのユーザーが所属するセキュリティ グループと配布グループの一覧を取得します。このメソッドは、パイプ (|) で区切られたグループの一覧を返します。

LdapAuthentication.GetGroups メソッドが文字列を操作して切り詰めを行うことに注意します。これにより、認証 cookie に格納される文字列の長さが短くなります。文字列が切り詰められていない場合の各グループの形式を以下に示します。
CN=...,...,DC=domain,DC=com
				
これは非常に長い文字列になる可能性があります。この文字列が cookie より長くなると、認証 cookie が作成されない場合があります。この文字列が cookie の長さを超える可能性がある場合は、グループの情報を ASP.NET のキャッシュ オブジェクトまたはデータベースに格納することや、グループの情報を暗号化して隠しフォーム フィールドに格納することができます。

Global.asax のコードを記述する

Global.asax ファイルのコードでは、Application_AuthenticateRequest イベント ハンドラを提供します。このイベント ハンドラは、Context.Request.Cookies コレクションから認証 cookie を取得し、cookie の暗号化を解除して、グループの一覧を取得します。この一覧は、FormsAuthenticationTicket.UserData プロパティに格納されます。各グループは、Logon.aspx ページに作成される、パイプで区切られた一覧に表示されます。

コードでは、文字列配列の文字列を解析して、GenericPrincipal オブジェクトを作成します。GenericPrincipal オブジェクトが作成されると、このオブジェクトは HttpContext.User プロパティに配置されます。
  1. ソリューション エクスプローラで、[Global.asax] を右クリックし、[コードの表示] をクリックします。
  2. 次のコードをコード ビハインド ファイル Global.asax.vb の最上部に追加します。
    Imports System.Web.Security
    Imports System.Security.Principal
    					
  3. Application_AuthenticateRequest の既存の空のイベント ハンドラを、次のコードに置き換えます。
    Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
            ' Fires upon attempting to authenticate the use
            Dim cookieName As String = FormsAuthentication.FormsCookieName
            Dim authCookie As HttpCookie = Context.Request.Cookies(cookieName)
    
            If (authCookie Is Nothing) Then
                'There is no authentication cookie.
                Return
            End If
    
            Dim authTicket As FormsAuthenticationTicket = Nothing
    
            Try
                authTicket = FormsAuthentication.Decrypt(authCookie.Value)
            Catch ex As Exception
                'Write the exception to the Event Log.
                Return
            End Try
    
            If (authTicket Is Nothing) Then
                'Cookie failed to decrypt.
                Return
            End If
    
            'When the ticket was created, the UserData property was assigned a
            'pipe-delimited string of group names.
            Dim groups As String() = authTicket.UserData.Split(New Char() {"|"})
    
            'Create an Identity.
            Dim id As GenericIdentity = New GenericIdentity(authTicket.Name, "LdapAuthentication")
    
            'This principal flows throughout the request.
            Dim principal As GenericPrincipal = New GenericPrincipal(id, groups)
    
            Context.User = principal
    
        End Sub
    					

Web.config ファイルを変更する

ここでは、Web.config ファイルの formsauthenticationauthorization の各要素の構成を行います。これらの変更により、認証されたユーザーのみがアプリケーションにアクセス可能となり、認証されていない要求は Logon.aspx ページにリダイレクトされます。この構成を変更することで、特定のユーザーやグループのみにアプリケーションへのアクセスを許可することができます。

Web.config ファイルの既存のコードを次のコードに置き換えます。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>    
  <system.web>
    <authentication mode="Forms">
      <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="60" path="/" >
      </forms>
    </authentication>	
    <authorization>	
      <deny users="?" />
      <allow users="*" />
    </authorization>	
    <identity impersonate="true" />
  </system.web>
</configuration>
				
configuration の要素 identity impersonate="true" / に注目してください。これにより ASP.NET で Microsoft インターネット インフォメーション サービス (IIS) の匿名アカウントとして構成されるアカウントの偽装が行われます。この構成を行うと、このアプリケーションに対するすべての要求は、構成済みのアカウントのセキュリティ コンテキストで実行されます。ユーザーは、Active Directory で認証されるための資格情報を提供しますが、Active Directory にアクセスするアカウントは、この構成済みのアカウントです。詳細については、「関連情報」を参照してください。

IIS で匿名認証を構成する

IIS で匿名認証を構成するには、次の手順を実行します。
  1. インターネット インフォメーション サービス (IIS) マネージャのコンソールで、"FormsAuthAd" の仮想ディレクトリを右クリックします。
  2. [プロパティ] をクリックし、[ディレクトリ セキュリティ] タブをクリックします。
  3. [認証とアクセス制御] または [匿名アクセスおよび認証コントロール] の下の [編集] をクリックします。
  4. [匿名アクセスを有効にする] または [匿名アクセス] チェック ボックスをオンにします。
  5. アプリケーションに対する匿名アカウントを、Active Directory に対するアクセス許可を持つアカウントに設定します。
  6. [IIS によるパスワードの管理を許可する] チェック ボックスをオフにします (IIS 5 の場合)。
デフォルトの IUSR_computername アカウントには、Active Directory に対するアクセス許可はありません。

Logon.aspx ページを作成する

次の手順を実行して、Logon.aspx という名前の ASP.NET Web フォームを新規作成します。
  1. ソリューション エクスプローラで、プロジェクトのノードを右クリックし、[追加] をポイントして、[Web フォームの追加] をクリックします。
  2. [ファイル名] ボックスに、Logon.aspx と入力し、[開く] をクリックします。
  3. ソリューション エクスプローラで、[Logon.aspx] を右クリックし、[デザイナの表示] をクリックします。
  4. デザイナで [HTML] タブをクリックします。
  5. 既存のコードを次のコードに置き換えます。
    <%@ Page language="vb" AutoEventWireup="true" %>
    <%@ Import Namespace="FormsAuthAd.FormsAuth" %>
    <html>
    	<body>
    		<form id="Login" method="post" runat="server">
    			<asp:Label ID="Label1" Runat="server">Domain:</asp:Label>
    			<asp:TextBox ID="txtDomain" Runat="server"></asp:TextBox><br>
    			<asp:Label ID="Label2" Runat="server">Username:</asp:Label>
    			<asp:TextBox ID="txtUsername" Runat="server"></asp:TextBox><br>
    			<asp:Label ID="Label3" Runat="server">Password:</asp:Label>
    			<asp:TextBox ID="txtPassword" Runat="server" TextMode="Password"></asp:TextBox><br>
    			<asp:Button ID="btnLogin" Runat="server" Text="Login" OnClick="Login_Click"></asp:Button><br>
    			<asp:Label ID="errorLabel" Runat="server" ForeColor="#ff3300"></asp:Label><br>
    			<asp:CheckBox ID="chkPersist" Runat="server" Text="Persist Cookie" />
    		</form>
    	</body>
    </html>
    <script runat="server">
    sub Login_Click(sender as object,e as EventArgs)
      Dim adPath as String = "LDAP://DC=..,DC=.." 'Path to your LDAP directory server
      Dim adAuth as LdapAuthentication = new LdapAuthentication(adPath)
      try
        if(true = adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text)) then
          Dim groups as string = adAuth.GetGroups()
    
          'Create the ticket, and add the groups.
          Dim isCookiePersistent as boolean = chkPersist.Checked
          Dim authTicket as FormsAuthenticationTicket = new FormsAuthenticationTicket(1, _
               txtUsername.Text,DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups)
    	
          'Encrypt the ticket.
          Dim encryptedTicket as String = FormsAuthentication.Encrypt(authTicket)
    		
          'Create a cookie, and then add the encrypted ticket to the cookie as data.
          Dim authCookie as HttpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
    
          if(isCookiePersistent = true) then
    		authCookie.Expires = authTicket.Expiration
          end if				
          'Add the cookie to the outgoing cookies collection.
          Response.Cookies.Add(authCookie)	
    
          'You can redirect now.
          Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false))
        
        else
          errorLabel.Text = "Authentication did not succeed. Check user name and password."
        end if
     
      catch ex as Exception
        errorLabel.Text = "Error authenticating. " & ex.Message
      end try
    end sub
    </script>
    					
  6. Logon.aspx ページのパスを変更して、LDAP ディレクトリ サーバーを指定します。
Logon.aspx ページは、ユーザーから情報を収集し、LdapAuthentication クラスのメソッドを呼び出すページです。このコードは、ユーザーの認証を行い、グループの一覧を取得した後、次の順序で処理を行います。
  • FormsAuthenticationTicket オブジェクトを作成します。
  • チケットを暗号化します。
  • 暗号化したチケットを cookie に追加します。
  • その cookie を HttpResponse.Cookies コレクションに追加します。
  • 最初に要求された URL に要求をリダイレクトします。

WebForm1.aspx ページを変更する

WebForm1.aspx ページは、最初に要求されるページです。ユーザーがこのページを要求すると、その要求は Logon.aspx ページにリダイレクトされます。この要求が認証されると、その要求は WebForm1.aspx ページにリダイレクトされます。
  1. ソリューション エクスプローラで、[WebForm1.aspx] を右クリックし、[デザイナの表示] をクリックします。
  2. デザイナで [HTML] タブをクリックします。
  3. 既存のコードを次のコードで置き換えます。
    <%@ Page language="vb" AutoEventWireup="true" %>
    <%@ Import Namespace="System.Security.Principal" %>
    <html>
    	<body>
    		<form id="Form1" method="post" runat="server">
    			<asp:Label ID="lblName" Runat="server" /><br>
    			<asp:Label ID="lblAuthType" Runat="server" />
    		</form>
    	</body>
    </html>
    <script runat="server">
    sub Page_Load(sender as object, e as EventArgs)
      lblName.Text = "Hello " + Context.User.Identity.Name & "."
      lblAuthType.Text = "You were authenticated using " &   Context.User.Identity.AuthenticationType & "."
    end sub
    </script>
    					
  4. すべてのファイルを保存して、プロジェクトをコンパイルします。
  5. WebForm1.aspx ページを要求します。要求は Logon.aspx にリダイレクトされます。
  6. ログオン資格情報を入力して、[Login] をクリックします。WebForm1.aspx にリダイレクトされると、ユーザー名が表示され、LdapAuthentication が Context.User.AuthenticationType プロパティに対応する認証の種類になります。
: マイクロソフトでは、フォーム認証を使用する場合は SSL (Secure Sockets Layer) の暗号化を使用することを推奨します。これは、このアプリケーションに SSL の暗号化を適用することで、ユーザーを識別するための基礎となる認証 cookie や送信されるその他の重要な情報が危険にさらされることを防止するためです。

関連情報

関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
306590 ASP.NET のセキュリティの概要
317012 ASP.NET のプロセス ID と要求 ID
306238 Visual Basic .NET を使用して、ASP.NET アプリケーションでフォーム ベースの認証にロール ベースのセキュリティを実装する方法
313091 Visual Basic .NET を使用してフォーム認証用のキーを作成する方法
313116 [PRB] フォーム認証要求が loginUrl ページにリダイレクトされない

プロパティ

文書番号: 326340 - 最終更新日: 2006年9月27日 - リビジョン: 4.3
この資料は以下の製品について記述したものです。
  • Microsoft ASP.NET 1.0
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft ASP.NET 1.1
  • Microsoft Visual Basic .NET 2003 Standard Edition
キーワード:?
kbconfig kbcookie kbhowtomaster kbsecurity kbwebforms KB326340
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com