ASP.Net Webforms混合模式身份验证

时间:2018-08-27 10:52:25

标签: webforms .net-4.5 mixed-mode

登录条件:

  • 如果是域用户/组(不应排除在组/用户中),则使用集成的或模拟的表单安全性进行身份验证。
  • 如果应该排除列表中的域用户/组,则使用并强制使用表单安全性。

使用所列的各种主题我能实现的目标是:

  • 使用临时cookie检索域用户详细信息,以将其身份验证为基于表单的用户。

Web.config(在需要时模糊):

  <system.web>
    <sessionState timeout="20"></sessionState>
    <compilation debug="true" targetFramework="4.0" />

    <httpRuntime enableVersionHeader="false" />

    <authentication mode="Forms">
      <forms loginUrl="~/Account/xxxxxx.aspx" timeout="2880" defaultUrl="~/Pages/xxxxxx.aspx" />
    </authentication>

    <machineKey xxxxxxxxxxxxxxxxxxx />

    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="xxxxxx"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="15" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10"
             applicationName="xxxxxx" />
      </providers>
    </membership>

    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="xxxxxx" applicationName="xxxxxx"/>
      </providers>
    </profile>

    <roleManager enabled="false">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="xxxxxx"  applicationName="xxxxxx" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="xxxxxx" />
      </providers>
    </roleManager>

    <healthMonitoring>
      <providers>
        <add connectionStringName="xxxxxx" buffer="false"   name="MsSqlAuditWebEventProvider" 
             type="System.Web.Management.SqlWebEventProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxx"  />
      </providers>

      <eventMappings>
        <add name="AuthenticationSuccess" 
             type="System.Web.Management.WebAuthenticationSuccessAuditEvent,System.Web, Version=4.0.0.0,Culture=neutral,PublicKeyToken=xxxxxx" />
        <add name="AuthenticationFailure"
         type="System.Web.Management.WebAuthenticationFailureAuditEvent,System.Web, Version=4.0.0.0,Culture=neutral,PublicKeyToken=xxxxxx" />
      </eventMappings>

      <rules>
        <add name="MsSql Auth Success Critical" eventName="AuthenticationSuccess"
         provider="MsSqlAuditWebEventProvider" profile="Critical" />
        <add name="MsSql Auth Failure Critical" eventName="AuthenticationFailure"
         provider="MsSqlAuditWebEventProvider" profile="Critical" />
      </rules>
    </healthMonitoring>
  </system.web>


  <system.webServer>

    <httpProtocol>
      <customHeaders>
        <remove name="X-Frame-Options" />
        <add name="X-Frame-Options" value="DENY" />
        <add name="X-Frame-Options" value="SAMEORIGIN" />
      </customHeaders>
    </httpProtocol>

    <validation validateIntegratedModeConfiguration="false" />

    <defaultDocument>
      <files>
        <add value="~/Account/xxxxxx.aspx" />
      </files>
    </defaultDocument>

    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="104857600" />
        <!--/*bytes*/-->
      </requestFiltering>
    </security>

  </system.webServer>

Global.asax

void Application_Start(object sender, EventArgs e)
{
    // Code that runs on application startup
}

void Application_End(object sender, EventArgs e)
{
    //  Code that runs on application shutdown
}

void Application_Error(object sender, EventArgs e)
{
    // Code that runs when an unhandled error occurs
}

void Application_BeginRequest(Object sender, EventArgs e)
{
    // Code that runs on application request startup
}

protected void Application_EndRequest(Object sender,
                                           EventArgs e)
{
    HttpContext context = HttpContext.Current;
    // we only want 302 redirects if they are for login purposes
    if (this.Response.StatusCode == 302 && this.Response.RedirectLocation.ToLower().Contains("/xxxxxx"))
    {
        string sWebUser = context.User.Identity.Name.ToString();
        // look for a setting on the QueryString to trigger a challenge
        if (!sWebUser.ToUpper().Contains("yyyyyy"))
        {
            this.Response.StatusCode = 401;
            this.Response.StatusDescription = "Authentication required";
            // 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)
{
    HttpContext context = HttpContext.Current;
    if (Request.IsAuthenticated && context.User.Identity is WindowsIdentity)
    {
        string sWebUser = context.User.Identity.Name.ToString();
        HttpCookie tempCookie = FormsAuthentication.GetAuthCookie("", false);
        if (sWebUser.ToUpper().Contains("yyyyyy"))
        {
            // create a temp cookie for this request only (not set in response)
            // note that we will be stripping the domain from the username as forms authentication doesn't capture this anyway
            //var tempCookie = FormsAuthentication.GetAuthCookie(Regex.Replace(context.User.Identity.Name, ".*\\\\(.*)", "$1", RegexOptions.None), false);
            tempCookie = FormsAuthentication.GetAuthCookie(sWebUser, 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
        context.User = new GenericPrincipal(new FormsIdentity(FormsAuthentication.Decrypt(tempCookie.Value)), (context.User.Identity as WindowsIdentity).Groups.Select(group => group.Value).ToArray());

        // now set the forms cookie
        FormsAuthentication.SetAuthCookie(context.User.Identity.Name, false);
    }
}

void Session_Start(Object sender, EventArgs e)
{
    HttpContext context = HttpContext.Current;
    string sWebUser = context.User.Identity.Name.ToString();

    if (sWebUser.ToUpper().Contains("xxxxxx"))
    {
        Response.Redirect("~/account/yyyyyy.aspx");
    }
}

void Session_End(object sender, EventArgs e)
{
    // Code that runs when a session ends. 
    // Note: The Session_End event is raised only when the sessionstate mode
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised.

}

是否有可能告诉我我所缺少的。我似乎很明显...

0 个答案:

没有答案