Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET 4.5 web窗体混合身份验证(集成模式)_C#_Asp.net_Forms Authentication_Windows Authentication_Mixed Authentication - Fatal编程技术网

C# ASP.NET 4.5 web窗体混合身份验证(集成模式)

C# ASP.NET 4.5 web窗体混合身份验证(集成模式),c#,asp.net,forms-authentication,windows-authentication,mixed-authentication,C#,Asp.net,Forms Authentication,Windows Authentication,Mixed Authentication,我正在尝试为我正在开发的intranet站点实现以下场景: 当用户登录到与网站位于同一域的PC并连接到与网站相同的网络时,访问intranet站点时,他将自动登录(windows身份验证) 当使用同一台PC的同一用户登录到与网站相同的域,但登录到与网站相同的其他网络(例如家庭网络)时,他将自动登录(windows身份验证) 当同一用户从他/她的家庭电脑(不属于域和网络的一部分)打开网站时,他将被重定向到表单身份验证登录页面,并能够使用他/她的广告凭据登录(具有广告成员身份的表单身份验证) 当其

我正在尝试为我正在开发的intranet站点实现以下场景:

  • 当用户登录到与网站位于同一域的PC并连接到与网站相同的网络时,访问intranet站点时,他将自动登录(windows身份验证)
  • 当使用同一台PC的同一用户登录到与网站相同的域,但登录到与网站相同的其他网络(例如家庭网络)时,他将自动登录(windows身份验证)
  • 当同一用户从他/她的家庭电脑(不属于域和网络的一部分)打开网站时,他将被重定向到表单身份验证登录页面,并能够使用他/她的广告凭据登录(具有广告成员身份的表单身份验证)
  • 当其他用户没有AD帐户且不在属于域的PC上时,他将被重定向到forms authentication登录页面,并且能够使用他/她的SQL用户scredentials登录(具有SQL成员资格的forms authentication)
除了一个重要的步骤外,我几乎可以完成这项工作。我现在掌握的代码是:

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中的设置

网站根级别

  • 启用匿名身份验证
  • 启用表单身份验证
  • 已启用Windows身份验证
WebLogin.aspx级别

  • 启用匿名身份验证
  • 启用表单身份验证
  • Windows身份验证已禁用
除了我定义是否可以使用windows身份验证的部分之外,我的所有方案都有效。根据我现在的设置,只有本地网络中的PC将继续使用windows身份验证。每当我在网络外使用我的电脑时,我都会看到forms authentication登录屏幕

是否有人建议我如何确定是否应该使用windows身份验证。我一直在使用当前用户登录的用户名,并检查它的域和使用,但我似乎无法得到的IIS设置的网站


提前谢谢

我用来找到这个解决方案的文章位于,仅仅检查他们的域和用户名是不够的。如果这就是你所需要的,一些黑客可以创建一个与你同名的域名,以及一个与用户匹配的用户名,然后可以自由访问。