Windowsで動作させるC#のプログラムの話で、特定サーバーにアクセスするためのIDと一致するものだけを許容するプログラムを作ろうとしていて、なかなか難航したのでその記録を残しておく。ようするに、IDとパスワードのうちのIDを取得したかったわけだけど、そのクライアントPCがドメイン参加なのかワークグループ参加なのかによってそのIDは変わってくるよねぇってことで、その分岐とWindows資格情報の取得というところが難問だったわけよ。
何はともあれ、そんなことをしているコード。
using CredentialManagement; public static string GetIdOfDomain(string domainName) { string id = ""; ManagementObject computer_system = new ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName)); object objPartOfDomain = computer_system["PartOfDomain"]; bool isDmn = (bool)objPartOfDomain; if(isDmn) { object objDomein = computer_system["Domain"]; string dName = objDomein.ToString(); if(string.Compare(domainName, dName, true) == 0) // 指定したドメインに参加しているので、ユーザーネームをIDとして返す return System.Environment.UserName; } // ワークグループまたは別のドメインに参加しているので資格情報で確認する Credential cm = new Credential(); cm.Target = domainName; cm.Type = CredentialType.DomainPassword; if (cm.Exists()) { cm.Load(); id = cm.Username; } return id; }
指定した名前と一致するドメインに参加しているならユーザー名がIDになるし、そうでないなら資格情報から取得しましょってこと。まだ動作確認してないので、このまま動くとは思っていない。IDがドメイン名まで含んだ状態もあるだろうから、そんな考慮をすればよい。それから、例外処理やらnewしたクラスの後始末もちゃんとやらなければ。
なお、CredentialというクラスはCredentialManagementというパッケージで、Nugetから取得する必要がある。Windows資格情報へのアクセスは、Win32APIをアンマネージドで実現しなければいけないところを、マネージドにアクセスできるようにラップしたもの。C#で書くのにアンマネージドな処理を書くのはイヤなもんだから、こういうパッケージを作ってくれる人がいるというのはうれしいね。