アプリケーションのフォームからログインするために、標準の Simple Membership モデルを使用しています。代わりに AD 経由でログインできるようにしたいと思います。
AD 経由でログインする場合、プロセスは次のようになります。
- AD がユーザーを認証することを確認しますが、プリンシパルの情報を使用しないでください。
- 提供された Active Directory ユーザー名を持つローカル ユーザーが存在するかどうかを確認します (ActiveDirectoryID という名前の UserProfile モデルにプロパティがあります)。
- 存在する場合は、この UserProfile のローカル ユーザー名を使用してローカル ログインを実行します。
問題: ローカル パスワードを取得できないため、AD 認証後にローカルでログインするには、パスワードなしでログインを強制できる必要があります。
次の戦略を検討しました。
- Websecurity.Login(string username) を許可する Websecurity の拡張メソッドを作成します。
- Web セキュリティに関係なく、何らかの方法でログイン ユーザーを手動で設定します。
これは実行可能/実行可能ですか? フレームワークがプレーンテキストのパスワードなしで必要な認証 Cookie を作成することは可能ですか? そして、どうすればこれを行うことができますか?
解決:
これは正しい解決策でした:
public ActionResult ActiveDirectoryLogin(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
try
{
DirectoryEntry entry = new DirectoryEntry("LDAP://DC=MyIntranet,DC=MyCompany,DC=com", model.UserName, model.Password);
object NativeObject = entry.NativeObject;
var internalUser = db.UserProfiles.Where(x => x.ActiveDirectoryID == model.UserName).SingleOrDefault();
if (internalUser != null)
{
FormsAuthentication.SetAuthCookie(internalUser.UserName, model.RememberMe);
return RedirectToLocal(returnUrl);
}
}
catch (DirectoryServicesCOMException)
{
// No user existed with the given credentials
}
catch (InvalidOperationException)
{
// Multiple users existed with the same ActiveDirectoryID in the database. This should never happen!
}
}
return RedirectToAction("Login");
}