单点登陆的ASP.NET应用程序设计

一,把用户登陆信息记录在数据库中,每次登陆去数据库里查找用户登陆状态,这种处理方式存在一种特列,如果用户非正常退出,容易出现死锁的情况.
    二,把用户信息记录在COOKEE中.这种方式没有进行研究,具体问题和风险有待研究.
    三,利用SESSION来保存用户信息.这种方式  HttpApplicationState保存了大量数据,对性能有一定的风险,暂时20个点登陆,还未出现问题.
    下面就第三种处理方式介绍如下:
    基础知识:
    HttpContext类:封装有关个别 HTTP 请求的所有 HTTP 特定的信息。 
    HttpApplicationState类:启用 ASP.NET 应用程序中多个会话和请求之间的全局信息共享。
    HttpSessionState类:提供对会话状态值以及会话级别设置和生存期管理方法的访问。 
    开发环境 VS.NET2003 + SqlServer2000 数据库是使用NORTHWIND
    
    为了今天分析特地编写了一个DEMO程序,这个DEMO很简单,只是为了说明单点处理方式.
    首先,设置web.config中的<appSettings>   
     <appSettings>
     <add key="SQLServerConnStr" value="uid=sa;password=123;database=Northwind;data source=(local)"/>
   </appSettings>

    和认证方式
    <authentication mode="Forms" >
  <forms  name=".ASPXAUTH"
      loginUrl="WebForm1.aspx"
      protection="All" 
      timeout="30"
      path="/" >
  
  </forms>
    </authentication> 
    
    然后编写业务处理类BLL.cs,里面主要是一些静态的登陆处理函数,代码如下:

/**************************************************************************************************
 * 作者:陈子文
 * 创建时间:2007-11-19
 * 功能:系统登陆认证管理类
 * 摘要:包括了登陆,注销,强迫对方下线方法
 * ***********************************************************************************************/
using System;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Security;
using System.Collections;
using System.Security;
using System.Configuration;


namespace SingleLoginTest
{
 /// <summary>
 /// BLL 的摘要说明。
 /// </summary>
 public class BLL
 {
  private static string _SqlConn = ConfigurationSettings.AppSettings["SQLServerConnStr"].ToString();
  

  public BLL()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
   //_SqlConn = ConfigurationSettings.AppSettings["SQLServerConnStr"].ToString();
   

  }

  /// <summary>
  /// 用户登陆
  /// </summary>
  /// <param name="userId"></param>
  /// <returns></returns>
  public static bool Login(string userId)
  {
   //初试返回变量
   bool retcode = false;

   if (userId == "")
    return retcode;

   //查询此用户存不存在
   if (GetUser(userId) == false)
   {
    return retcode;
   }
   else
   {
    retcode = true ;
   }

   //判断有没有登陆过
   IsUserExist( userId);

   HttpContext.Current.Session["Name"]=userId;
   FormsAuthentication.RedirectFromLoginPage(userId, false);
   FormsAuthentication.SetAuthCookie(userId, false);
   //写认证
   Hashtable _hash = (Hashtable)HttpContext.Current.Application["online"];
   if (_hash == null)
   {
    _hash = new Hashtable();
    HttpContext.Current.Application.Add("online",_hash);
   }

   _hash[HttpContext.Current.Session.SessionID] = HttpContext.Current.Session ;
   HttpContext.Current.Application["online"] = _hash;
  
   return retcode;
   //返回

  }

  /// <summary>
  /// 判断用户是否在线
  /// </summary>
  /// <param name="userId"></param>
  /// <returns></returns>
  public static bool IsUserExist(string userId)
  {
   bool retcode = false;
   Hashtable _table = (Hashtable)HttpContext.Current.Application["online"];
   if (_table == null)
    return retcode;

   IDictionaryEnumerator e = _table.GetEnumerator();
   while (e.MoveNext())
   {
    System.Web.SessionState.HttpSessionState session = (System.Web.SessionState.HttpSessionState)e.Value;
    if (session == null)
     continue;
    string tmpuserId = session["Name"].ToString();
    if ( userId == tmpuserId )   //存在用户
    {
     //清除他
     session.Clear();
     session.Abandon();
     _table.Remove(e);
     HttpContext.Current.Application["online"] = _table;

     string script = "<script language=javascript>alert('在异地登陆,迫使他下线!')</script>";

     HttpContext.Current.Response.Write(script);

     retcode = true;
     break;
    }
   }

   return retcode;

  }


  /// <summary>
  /// 注销
  /// </summary>
  public static void  LoginOut()
  {
   // Clear the authentication ticket
   FormsAuthentication.SignOut();
   // Clear the contents of their session
   HttpContext.Current.Session.Clear();
   // Tell the system to drop the session reference so that it does
   // not need to be carried around with the user
   HttpContext.Current.Session.Abandon();
  }

  
  /// <summary>
  /// 删除用户
  /// </summary>
  /// <param name="userId"></param>
  public static void Remove(string userId)
  {
   Hashtable _table = (Hashtable)HttpContext.Current.Application["online"];

   if (_table == null)
    return ;

   IDictionaryEnumerator e = _table.GetEnumerator();
   while (e.MoveNext())
   {
    System.Web.SessionState.HttpSessionState session = (System.Web.SessionState.HttpSessionState)e.Value;
    string _userid = session["Name"].ToString();
    if (_userid == userId)
    {
     session.Clear();
     session.Abandon();
     _table.Remove(e);
     HttpContext.Current.Application["online"] = _table;
     break;
    }
   }

  }

  /// <summary>
  /// 查询用户是否存在
  /// </summary>
  /// <param name="userId"></param>
  /// <returns></returns>
  public static bool GetUser(string userId)
  {
   //
   bool retcode = false;

   using( SqlConnection cn = new SqlConnection(_SqlConn))
   {
    cn.Open();
    string sql="SELECT COUNT(*) FROM Customers WHERE CustomerId='"+userId+"'";
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = cn;
    cmd.CommandText = sql;
    int count = int.Parse(cmd.ExecuteScalar().ToString());
    if (count > 0 )
     retcode=true;
   }

   return retcode;
  }
 }
}
    最后添加两个webform.aspx,演示如下 (没有办法刚刚用博客,图片不太会处理,ps下自己)
    我简单把代码粘贴下啦:
    <form id="Form1" method="post" runat="server">
   <asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 176px; POSITION: absolute; TOP: 208px"
    runat="server"></asp:TextBox>
   <asp:Label id="Label1" style="Z-INDEX: 102; LEFT: 120px; POSITION: absolute; TOP: 208px" runat="server">用户ID:</asp:Label>
   <asp:Button id="btnLogin" style="Z-INDEX: 103; LEFT: 272px; POSITION: absolute; TOP: 248px"
    runat="server" Text="Login"></asp:Button>
  </form>
    后台代码:

 private void btnLogin_Click(object sender, System.EventArgs e)
  {
   if ( BLL.Login(TextBox1.Text.Trim())== false )
   {
    string _script ="<script language=javascript>alert('登陆失败')</script>";
    HttpContext.Current.Response.Write(_script);
   }
   else
   {
    string _script ="<script language=javascript>alert('登陆成功')</script>";
    HttpContext.Current.Response.Write(_script);
   };

  }

你可能感兴趣的:(asp.net)