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#で書くのにアンマネージドな処理を書くのはイヤなもんだから、こういうパッケージを作ってくれる人がいるというのはうれしいね。