将集成Windows认证并使用了身份模拟的ASP.net应用改成Form认证

先在Web.config里设置成Form认证:

 <authentication mode="Forms">
     <forms loginUrl="~/Login.aspx" name=".ASPXFORMSAUTH" />
 </authentication>

  <authorization>
      <deny users="?" />
      <allow users="*" /> 
  </authorization>

当然还得使用Session

<sessionState   mode="InProc"/>

 

以及配置站点/虚拟目录为匿名认证

 

然后是一个身份模拟的辅助类:

publicclass ImpersonateHelper

{

 

      public const string SystemUserToken = "SystemUserToken";

 

      public ImpersonateHelper()

      {}

 

      [DllImport("advapi32.dll", SetLastError=true)]

      public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,

             int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

 

 

      [DllImport("kernel32.dll", CharSet=CharSet.Auto)]

      public extern static bool CloseHandle(IntPtr handle);

 

      [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]

      public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,

             int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

 

 

      public static IntPtr LogonUser(string userName, string password)

      {

             string[] userInfo = userName.Split('//');

 

             IntPtr tokenHandle = IntPtr.Zero;

             IntPtr dupeTokenHandle = new IntPtr(0);

 

             const int LOGON32_PROVIDER_DEFAULT = 0;

             //This parameter causes LogonUser to create a primary token.

             const int LOGON32_LOGON_INTERACTIVE = 2;

 

             // Call LogonUser to obtain a handle to an access token.

             bool returnValue = LogonUser(userInfo[1], userInfo[0], password, LOGON32_LOGON_INTERACTIVE,

                    LOGON32_PROVIDER_DEFAULT, ref tokenHandle);

             if (false == returnValue)

             {

                    int ret = Marshal.GetLastWin32Error();

                    throw new System.ComponentModel.Win32Exception(ret);

             }

             return tokenHandle;

      }

 

      public static void Impersonate(IntPtr token)

      {

             WindowsIdentity identity = new WindowsIdentity(token);

             identity.Impersonate();

             ///WindowsImpersonationContext impersonatedUser = newId.Impersonate();

             ///WindowsImpersonationContext

      }

 

      private const string TokenCollection = "TokenCollection";

      public static void StoreUserToken(System.IntPtr token)

      {

             System.Web.HttpContext context = System.Web.HttpContext.Current;

             object o = context.Application[TokenCollection];

             if (o == null)

             {

                    o = new System.Collections.Hashtable();

                    System.Web.HttpContext.Current.Application[TokenCollection] = o;

             }

 

             System.Collections.Hashtable tokens = o as System.Collections.Hashtable;

             

             tokens[context.Request["ASP.NET_SessionId"]] = token;

      }

 

      public static void RemoveToken(string sessionId)

      {

             System.Web.HttpContext context = System.Web.HttpContext.Current;

             object o = context.Application[TokenCollection];

             if (o != null)

             {

                    System.Collections.Hashtable tokens = o as System.Collections.Hashtable;

                    if (tokens.ContainsKey(sessionId))

                    {

                           tokens.Remove(sessionId);

                    }

             }

      }

 

      public static System.IntPtr GetCurrentUserToken()

      {

             System.Web.HttpContext context = System.Web.HttpContext.Current;

             object o = context.Application[TokenCollection];

             if (o == null)

             {

                    return System.IntPtr.Zero;

             }

 

             System.Collections.Hashtable tokens = o as System.Collections.Hashtable;

 

             string sessionId = context.Request["ASP.NET_SessionId"];

             if (sessionId == null || sessionId == "")

             {

                    return System.IntPtr.Zero;

             }

             object token = tokens[sessionId];

             if (token == null)

             {

                    return System.IntPtr.Zero;

             }

             return (System.IntPtr)token;

      }

}

Login.aspxLoginClick事件通过调用Windows API获取登陆凭据,并按SessionID为键值保存在Application中,接着模拟身份并转向原请求的页面

System.IntPtr token = ImpersonateHelper.LogonUser(userName, password);

ImpersonateHelper.StoreUserToken(token);

ImpersonateHelper.Impersonate(token);

FormsAuthentication.RedirectFromLoginPage(userName, false);

 然后在Global.asax.cs中的BeginRequest时取回与当前Session相关的Windows凭据,接着模拟成该身

protectedvoid Application_BeginRequest(Object sender, EventArgs e)

{

      System.IntPtr token = ImpersonateHelper.GetCurrentUserToken();

      if (token == System.IntPtr.Zero)

      {

             System.Web.HttpContext context = System.Web.HttpContext.Current;

             string currentUrl = context.Request.Url.ToString();

             if (currentUrl.ToLower().IndexOf("/login.aspx?returnurl=") == -1)

             {

                    context.Response.Redirect("~/Login.aspx?ReturnUrl=loader.aspx");

             }

      }

      else

      {

             ImpersonateHelper.Impersonate(token);

      }

}

最后一步,防止用户在Session超时后仍使用原SessionID,注:ASP.net 2.0中可以通过Web.Config配制成当Session超时后强制生成新的SessionId

protectedvoid Session_Start(Object sender, EventArgs e)

{

 

      if (Session.IsNewSession)

      {

             ImpersonateHelper.RemoveToken(Session.SessionID);

      }

}

 

 


版权声明:本文为cnlike原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。