分享

FormsAuthentication.SignOut() 会删除所有登录凭证

 A_POST 2013-12-18

FormsAuthentication.SignOut() 会删除所有登录凭证  

2012-04-25 17:19:59|  分类: WEB 技术 |  标签:formsauthentication.  signout()  |字号 订阅

void m_view_lnbExit_Exit(object sender, EventArgs e)
        {
           FormsAuthentication.SignOut();
            HttpContext.Current.Session.Abandon();
            FormsAuthentication.RedirectToLoginPage();
        }
使用上述方法会删除所有登录凭证

这样会现问题,两个用户登录,在一个客户端。一个退出了,另一个没有退出。另一个会被强行退出。

HttpContext.Current.Session.Abandon(); 会清除客户端相关所有session.

所以,另一用户的session也会被清除。

解决办法一,用Session验证,不用weform验证,每次在basePage基类里验证.这种办法有点老土,但可以做到多个用户在一个客户端同时登陆.登录时,session里放一个用于存储已登录用户列表,然后还要通过URL传给后续页当前登录用户信息,接收页面要记录当前操作是哪个用户在操作.哪个用户退出时,就从session中移出登录哪个用户数据.转到登录界面.基类验证时注意,捕获URL传来的用户信息,看用户信息是否在seeeion里的用户登录列表.如果不在,或没有传递参数就拒绝访问.                  

解决办法二,使用Cookie,使用Webform验证,但不使用 HttpContext.Current.User.Identity.Name,提取数据依据或做为判断当前用户,因为HttpContext.Current.User.Identity.Name里面记录的是最后一个用户登录的信息.不使用SignOut();退出,因为SignOut();是删除所有用户登录凭证.

登录时建立票据信息:

   System.Web.Security.FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, "userName", DateTime.Now, DateTime.Now.AddDays(3), true, string.Empty);
            string cookieString = System.Web.Security.FormsAuthentication.Encrypt(ticket);
            HttpCookie cookie = new HttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName);
            cookie.Value = cookieString;
            cookie.Expires = DateTime.Now.AddDays(3);
            HttpContext.Current.Response.Cookies.Add(cookie);

然后重定向,指定页.

需要使用户获取ticket 用户信息

       HttpCookie cookie = HttpContext.Current.Request.Cookies["userName"];
            string userName = string.Empty;
            if (cookie != null)
            {
                string cookieString = cookie.Value;
                System.Web.Security.FormsAuthenticationTicket ticket = System.Web.Security.FormsAuthentication.Decrypt(cookieString);
            }

退出时,删除相应的Cookie.HttpContext.Current.Response.Cookies.Remove("UserName");
如果通地址栏,直接进,可以进入(有待研究),就拿用户名名去查找cookie是否存在,如果不存在,就拒绝访问.

解决办法三,使用 webform 验证,可以使用HttpContext.Current.User.Identity.Name,使用SignOut();退出,但一个客户端只允许一个用户登录.不允许多个用户同时在一个客户端登录.允许同一用户或不同用户,在不同客户端同时登录.

登录:

   string currentUser = HttpContext.Current.User.Identity.Name;
            if (currentUser == string.Empty) //没用户在本客户端登录.
            {
                 ...//验证逻辑
                FormsAuthentication.SetAuthCookie(m_view.UserName.ToString(), true);
              }
            else
            {
                m_view.Message = ""已经有用户登录,请先退出,再登录!"";
            }

验证:这种方式就是不用担会从地址栏直接进入..net系统会自动拦截.

使用用户信息:HttpContext.Current.User.Identity.Name

退出:SignOut();

为防止用户直接关闭浏览器,而不点退出按钮,导至用户在此客户端无法再进入.

在页面如下代码

 <script type="text/javascript"> 
<!--
        window.onbeforeunload = function () {

           if (event.clientY < 0 || event.altKey) {
            var callFrom = $('#lnbOut);
                __doPostBack(callFrom.attr('id').replace(/_/g, '$'), '');  //这里可以放置你想做的操作代码 
                alert("您已经安全退出本系统。");
            }
        }  
// --> 
    </script>

lnbOut是退出按钮id.

强制执行一次,退出.

webconfig如下:

<?xml version="1.0"?>
<configuration>
 <configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
 </configSections>
 <appSettings>
  <add key="CONFIGRATION_FILE" value="configfile/sssfdwe.xml"/>
 </appSettings>
 <connectionStrings>
  <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
 </connectionStrings>
 <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8"/>
  <compilation debug="true" targetFramework="4.0"/>
  <authentication mode="Forms">
   <forms loginUrl="~/Login.aspx" timeout="1200" protection="All"
 name=".ASPXAUTHCBS"  path="/" cookieless="UseCookies" />
    </authentication>
  <membership>
   <providers>
     <clear/>
    <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/"/>
   </providers>
  </membership>
  <profile>
   <providers>
    <clear/>
    <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
   </providers>
  </profile>
  <roleManager enabled="false">
   <providers>
    <clear/>
    <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/"/>
    <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/"/>
   </providers>
  </roleManager>
    <customErrors mode="On" defaultRedirect="ErrorPage.aspx">
    </customErrors>
    <httpRuntime requestValidationMode="3.0" />
    <pages validateRequest="false" />
    <sessionState timeout="1200" mode="InProc" cookieless="true" cookieName="CookieCsdfwerfS" />
  </system.web>
  <location path="Scripts">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <location path="Styles">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <location path="images">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
  <location path="~/ErrorPage.aspx">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location>
 <system.webServer>
  <modules runAllManagedModulesForAllRequests="true"/>
 </system.webServer>
 <!--- log4net配置 -->
 <log4net>
  <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -->
  <!-- Set root logger level to ERROR and its appenders -->
  <root>
   <level value="ALL"/>
   <appender-ref ref="SysAppender"/>
  </root>
  <!-- Print only messages of level DEBUG or above in the packages -->
  <logger name="WebLogger">
   <level value="DEBUG"/>
  </logger>
  <appender name="SysAppender" type="log4net.Appender.RollingFileAppender,log4net">
   <!-- 日志目录 -->
   <param name="File" value=".\ssdflog/"/>
   <param name="AppendToFile" value="true"/>
   <!-- 日志最多文件数 -->
   <param name="MaxSizeRollBackups" value="20"/>
   <!-- 日志文件最大长度KB,MB,GB -->
   <param name="MaximumFileSize" value="10MB"/>
   <param name="RollingStyle" value="Date"/>
   <param name="DatePattern" value=""Logs_"yyyyMMdd".txt""/>
   <param name="StaticLogFileName" value="false"/>
   <!-- 日志布局格式 -->
   <layout type="log4net.Layout.PatternLayout,log4net">
    <!--
        <param name="ConversionPattern" value="%d [%t] %-5p - %m%n"/>
        <param name="Header" value="&#xA;header&#xA;"/>
        <param name="Footer" value="&#xA;footer&#xA;"/>
        -->
    <header value="[Header]&#xA;"/>
    <footer value="[Footer]&#xA;"/>
    <conversionPattern value="%d [%t] %-5p - %m%n"/>
   </layout>
  </appender>
 </log4net>
</configuration>

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多