開発中のイントラネット サイトで次のシナリオを実現しようとしています。
- Webサイトと同じドメイン内のPCにログインし、Webサイトと同じネットワークに接続しているユーザーがイントラネットサイトにアクセスすると、自動的にログインします(Windows認証)。
- 同じ PC を使用している同じユーザーが、Web サイトと同じドメインにログインしているが、Web サイトとは別のネットワーク (ホーム ネットワークなど) にログインしている場合、そのユーザーは自動的にログインされます (Windows 認証)。
- 同じユーザーが、ドメインおよびネットワークの一部ではない自宅の PC から Web サイトを開くと、フォーム認証ログイン ページにリダイレクトされ、AD 資格情報 (フォーム認証) でログインできます。 ADメンバーシップ付き)
- AD アカウントを持たず、ドメインの一部である PC を使用していない他のユーザーは、フォーム認証ログイン ページにリダイレクトされ、SQL ユーザー資格情報でログインできます。 (SQL メンバーシップによるフォーム認証)
1つの重要なステップを除いて、これはほとんど機能しています。私が今持っているコードはこれです:
Global.asax
protected void Application_EndRequest(object sender, EventArgs e)
{
// we only want 302 redirects if they are for login purposes
if (this.Response.StatusCode == 302 && this.Response.RedirectLocation.Contains("/WinLogin"))
{
if (Request.UserHostAddress.StartsWith("10.1.34") || Request.UserHostAddress.StartsWith("10.1.35"))
{
this.Response.StatusCode = 401;
// note that the following line is .NET 4.5 or later only
// otherwise you have to suppress the return URL etc manually!
this.Response.SuppressFormsAuthenticationRedirect = true;
}
}
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated && HttpContext.Current.User.Identity is WindowsIdentity)
{
// note that we will be stripping the domain from the username as forms authentication doesn't capture this anyway
// create a temp cookie for this request only (not set in response)
var tempCookie = FormsAuthentication.GetAuthCookie(Regex.Replace(HttpContext.Current.User.Identity.Name, ".*\\\\(.*)", "$1", RegexOptions.None), false);
// set the user based on this temporary cookie - just for this request
// we grab the roles from the identity we are replacing so that none are lost
HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(FormsAuthentication.Decrypt(tempCookie.Value)), (HttpContext.Current.User.Identity as WindowsIdentity).Groups.Select(group => group.Value).ToArray());
// now set the forms cookie
FormsAuthentication.SetAuthCookie(HttpContext.Current.User.Identity.Name, false);
}
}
WinLogin.aspx:
var membershipProvider1 = Membership.Providers["MyAdMembershipProvider"];
var membershipProvider2 = Membership.Providers["MySqlMembershipProvider"];
if (membershipProvider1.ValidateUser(TextBox1.Text, TextBox2.Text) || membershipProvider2.ValidateUser(TextBox1.Text, TextBox2.Text))
{
// set the forms auth cookie
FormsAuthentication.SetAuthCookie(TextBox1.Text, false);
// reset request.isauthenticated
var authCookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
var roles = authTicket.UserData.Split(',');
System.Web.HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
}
}
FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, false);
}
Web.config
<authentication mode="Forms">
<forms name=".ASPXFORMSDEMO" loginUrl="WinLogin.aspx" />
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<location path="/WinLogin.Aspx">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
IIS の設定
Web サイトのルート レベル
- 匿名認証が有効
- フォーム認証有効
- Windows 認証有効
WebLogin.aspx レベル
- 匿名認証有効
- フォーム認証有効
- Windows 認証無効
Windows認証を使用できるかどうかを定義する部分を除いて、すべてのシナリオが機能します。現在のセットアップでは、ローカル ネットワーク内の PC のみが引き続き Windows 認証を使用します。PC をネットワークの外に持ち出すと、フォーム認証のログイン画面が表示されます。
Windows認証を使用する必要があるかどうかを判断する方法を誰かが提案していますか? 現在のユーザーがログインしているユーザー名を使用してそのドメインを確認し、それを使用することに取り組んできましたが、Web サイトの IIS 設定の時点でそれを取得できないようです。
前もって感謝します!