8

ActiveDirectory と標準フォームのログインの両方を機能させようとしていますが、1 つのことが妨げになっています。現在の Windows ユーザーの名前を取得できません。最も近いのは ですがvar i = WindowsIdentity.GetCurrent();、これで IIS アプリ プール ユーザーの名前がわかります。IIS で匿名認証、フォーム認証、および Windows 認証を有効にしています。AD からユーザーをロードできるので、web.config が正しくセットアップされていると仮定します。

編集:これは私のweb.configです(Facadeプロバイダーを使用):

<membership defaultProvider="HybridMembershipProvider">
      <providers>
        <clear />
        <add name="HybridMembershipProvider" type="MyApp.Data.HybridMembershipProvider" AspNetProviderName="AspNetSqlMembershipProvider" ActiveDirectoryProviderName="ADMembershipProvider" />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MyAppConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
        <add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" 
            attributeMapUsername="sAMAccountName" enableSearchMethods="true" attributeMapEmail="mail"/>
      </providers>
    </membership>

編集 2: これが私の IIS セキュリティ設定です。

IIS セキュリティのセットアップ

4

5 に答える 5

5

IISでASP.Net偽装をオンにすると、必要なユーザー名を取得できます。これは、そのデータがメンバーシッププロバイダー/ ADのフォームにあり、匿名ではない場合にのみ機能します。

また、フォームベースの認証とWindows / ADベースの認証を混在させることもできますが、お勧めしません。あなたがそれをする必要があるならば、これを見てください。

編集:私はあなたが望んでいたことを誤解したと思うので、ここに前述の解決策で何が起こっているのかについての高レベルの註解があります:

匿名認証をオフにし、Asp.Net偽装をオンにすると、誰かがサイトにアクセスするたびにIISは401チャレンジを実行します。
すべてが同じドメインにある場合、WebブラウザはIISにクレデンシャルを送信し、IISはそれらをActive Directoryに対して検証し、ADはIISに使用するIDを与えます。

Asp.Netの偽装をオンにすると、IISはそのIDを現在のスレッド/要求にバインドします。したがって、認証が行われた後、現在のスレッドIDからユーザー名を取得し、次のようにActiveDirectoryにクエリを実行できます。

using System.Threading;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

......

PrincipalContext pc = null;
UserPrincipal principal = null;

try
{
    var username = Thread.CurrentPrincipal.Identity.Name;
    pc = new PrincipalContext(ContextType.Domain, "active.directory.domain.com");
    principal = UserPrincipal.FindByIdentity(pc, username);

    var firstName = principal.GivenName ?? string.Empty
    var lastName = principal.Surname ?? string.Empty
    return string.Format("Hello {0} {1}!", firstName, lastName);
}
catch ...
finally
{
    if (principal != null) principal.Dispose();
    if (pc != null) pc.Dispose();
}
于 2012-05-14T14:05:25.620 に答える
1

Active Directory でフォーム認証を使用している場合は、これを試してください。

Context.User.Identity.Name

//コードスニペット

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

参照:
ASP .NET からの Active Directory 認証
フォーム認証と Visual Basic .NET を使用して Active Directory に対して認証を行う方法 安全な ASP.NET アプリケーションの構築: 認証、承認、および安全な通信

参照: ASP.NET で Windows 認証をさまざまな方法で使用できます。

  • 偽装なしの Windows 認証。これがデフォルト設定です。ASP.NET は、アプリケーションのプロセス ID (既定では Windows Server 2003 のネットワーク サービス アカウント) を使用して操作を実行し、リソースにアクセスします。

  • 偽装による Windows 認証。このアプローチでは、認証されたユーザーになりすまし、その ID を使用して操作を実行し、リソースにアクセスします。

  • 固定 ID の偽装による Windows 認証。このアプローチでは、固定の Windows アカウントを偽装して、特定の ID を使用してリソースにアクセスします。Windows Server 2003 では、この偽装アプローチを避ける必要があります。代わりに、カスタム サービス ID を持つカスタム アプリケーション プールを使用してください。

ドキュメントに従って、認証されたユーザーの Windows トークンを取得できます。

IIdentity WinId= HttpContext.Current.User.Identity;
WindowsIdentity wi = (WindowsIdentity)WinId;

何か問題がある場合は 、MSDN のドキュメント「方法: ASP.NET 2.0 で Windows 認証を使用する」に従って、アプリケーションの偽装方法を確認してください。

ScottGu の記事「レシピ: イントラネット ASP.NET Web アプリケーション内で Windows 認証を有効にする」を参照してください。

于 2012-05-14T14:21:32.670 に答える
1

User.Identity.NameWindows認証を使用した場所で作成した.Netアプリは、ADユーザー名を取得するために引き続き使用できます。これには通常、もちろん DC が含まれ、ユーザーの SAM アカウント名が返されます。私は両方を同時に実装しようとしていませんでしたがUser.Identity.Name、確かに別々に動作します

于 2012-05-14T13:49:35.690 に答える
0

これは、少し前に ASP.NET MVC アプリで使用したコードの一部です。役に立ちましたか?

    private static void CheckIfUserExists(string p)
    {
        try
        {
                var user = (from x in Data.EntityDB.UserInfoes where x.SAMAccountName == p select x).FirstOrDefault();
                DirectoryEntry entry = new DirectoryEntry(Properties.Settings.Default.LDAPPath); //this is the connection to your active directory
                DirectorySearcher search = new DirectorySearcher(entry);
                search.PropertiesToLoad.Add("*");
                search.Filter = "(&(sAMAccountName=" + p + ")(objectCategory=person))";
                SearchResult searchResult = search.FindOne();
            //If the user under the alias is not found, Add a new user. Else, update his current data
            if (user == null)
            {
                XXXXXXX.Models.UserInfo newUserEntry = new Models.UserInfo
                {
                    SAMAccountName = p,
                    First_Name = searchResult.Properties.Contains("givenName") ? searchResult.Properties["givenName"][0].ToString() : string.Empty,
                    Last_Name = searchResult.Properties.Contains("sn") ? searchResult.Properties["sn"][0].ToString() : string.Empty,
                    Title = searchResult.Properties.Contains("title") ? searchResult.Properties["title"][0].ToString() : string.Empty,
                    Office = searchResult.Properties.Contains("l") ? searchResult.Properties["l"][0].ToString() : string.Empty,
                    Country = searchResult.Properties.Contains("c") ? searchResult.Properties["c"][0].ToString() : string.Empty,
                    Telephone = searchResult.Properties.Contains("telephoneNumber") ? searchResult.Properties["telephoneNumber"][0].ToString() : string.Empty,
                    Mobile_Phone = searchResult.Properties.Contains("mobile") ? searchResult.Properties["mobile"][0].ToString() : string.Empty,
                    Email_Address = searchResult.Properties.Contains("mail") ? searchResult.Properties["mail"][0].ToString() : string.Empty,
                    Image_Path = string.Format(Properties.Settings.Default.UserPicturePath, p),
                    LastUpdate = DateTime.Now,
                };

アップデート

この抽出で別のデータベースにもクエリを実行したことに注意してください。Linq ステートメントはすべて無視してください。DirectoryEntryDirectorySearcherおよびクラスは、SearchResult必要なものを支援するはずです。

更新 2 変数 p は、HttpContext.Current.User.Identityプロパティに置き換えることができます

更新 3 LDAP 名の現在のリストは次のとおりです (searchResult.Properties.Contains("") が表示されます)ここでは、アクティブ ディレクトリ内のさまざまなユーザー属性を指しています。

于 2012-05-14T13:54:40.177 に答える
-1

私は試してみます:

var i = Environment.CurrentUser;

私のクラスも使用できます: http://pastebin.com/xnYfVsLX

于 2012-05-14T13:48:59.420 に答える