使用SQL Server保存Session状态,实现单点登陆

在作一些应用网站时,咱们可能会碰到这样一种状况:整个项目是由多个网站组成的,而咱们要实现用户从一个站点登陆后,跳转到其余网站不须要重复登陆,即实现单点登陆。目前实现单点登陆的技术也有好几种,这篇文章描述一下如何使用ASP.NET2.0和SQL Server来实现单点登陆。通常在用户登陆成功后,咱们须要把用户登陆成功的信息保存在Session里,可是Session的值只能保存在用户当前访问的站点下,只要咱们实现了Session的跨站共享,也就基本上实现了用户在一个站点登陆成功后在其余站点不须要重复登陆,在这里,咱们使用SQL Server来保存Session状态,实现多个站点共享Session。html

  开发环境:WindowsXP、VS200五、.NET Framework 2.0、SQL Server 2000web

  首先咱们须要建立一个单独的数据库来保存Session状态,安装了Framework2.0后,咱们能够在“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727”目录下找到一个“InstallPersistSqlState.sql”的SQL文件,这个文件就是用来建立保存Session状态的数据库,只须要在查询分析器中执行一下就能够了,固然也能够使用“UninstallPersistSqlState.sql”这个文件来卸载已建立的状态数据库。sql

  “InstallPersistSqlState.sql”执行完毕后,刷新一下对象浏览器,咱们就能够看到一个叫作“ASPState”的数据库,数据库中有两个表,“ASPStateTempApplications”是用来存储全部使用SQLServer保存状态的站点的,“ASPStateTempSessions”固然就是用来保存全部Session的了。以下图:数据库

张礼现的CSDN博客

  建立完数据库后,咱们能够新建一个测试网站,来看一下Session状态是否能够保存到数据库中,固然测试以前咱们还须要对web.config文件作一些设置。打开web.config,在<system.web>标签下建立<sessionState>标签,mode属性是说明把Session状态保存在什么地方,有状态服务器、内存、数据库等,这里咱们要选择SQLServer。设置以下所示:浏览器

 

[xhtml]  view plain copy
 
 
  1. <system.web>  
  2.     <sessionState mode="SQLServer" sqlConnectionString="Data Source=127.0.0.1;User ID=sa;Password=;" timeout="60"/>  
  3. </system.web>  

 

  在测试Session状态时,有一点须要注意,就是若是咱们在程序中没有给Session任何值,Session状态是不向数据库中保存的。咱们随便给Session一个键值,运行后,使用查询分析器来看一下“ASPState”数据库中两个表的内容,以下:服务器

ASPStateTempApplications表session

张礼现的CSDN博客

ASPStateTempSessions表app

张礼现的CSDN博客

下图为测试页上显示的Session内容:测试

张礼现的CSDN博客

  在这里咱们须要解释一下AppID和SessionID,先看一下下面两张图中的SessionID,表ASPStateTempSessions中的SessionID比页面上多出了8位,就是后面的“64021378”,这段字符串实际上是表ASPStateTempApplications里的AppID的十六进制表示,能够看出数据库中SessionID的值,是“页面SessionID+AppID”组合而成的。网站

  既然咱们要实现的是跨站共享Session,那么咱们须要建立另一个测试站点2,也按照上述方法把Session状态保存到数据库中,下图显示了在浏览器中访问这两个站点后,“ASPStateTempSessions”表保存的Session信息:

张礼现的CSDN博客

  这两条SessionID前面的部分相同,不一样的地方是后面8位标识AppID的值不一样,在ASPState库中,判断是否为同一用户是根据SessionID为条件的,虽然这里用户是同一人,但访问的站点不一样,SessionID也就不相同了。下面咱们要作的就是忽略SessionID里面的站点标识,这样就ASPState就能够把来自同一用户的多个站点访问当作是同一站点访问,Session值也就能够在多个站点共享了。

  在ASPState库里,咱们须要修改“TempGetAppID”这个存储过程,把里面两句“WHERE AppName = @appName”注释掉就能够了。在这里,应注意修改完存储过程后,须要把ASP.NET网站程序从新启动一下。

 

[c-sharp]  view plain copy
 
 
  1. ALTER  PROCEDURE dbo.TempGetAppID  
  2. @appName    tAppName,  
  3. @appId      int OUTPUT  
  4. AS  
  5. SET @appName = LOWER(@appName)  
  6. SET @appId = NULL  
  7.   
  8. SELECT @appId = AppId  
  9. FROM [ASPState].dbo.ASPStateTempApplications  
  10. --WHERE AppName = @appName  
  11.   
  12. IF @appId IS NULL BEGIN  
  13.     BEGIN TRAN          
  14.   
  15.     SELECT @appId = AppId  
  16.     FROM [ASPState].dbo.ASPStateTempApplications WITH (TABLOCKX)  
  17.     --WHERE AppName = @appName  
  18.       
  19.     IF @appId IS NULL  
  20.     BEGIN  
  21.         EXEC GetHashCode @appName, @appId OUTPUT  
  22.           
  23.         INSERT [ASPState].dbo.ASPStateTempApplications  
  24.         VALUES  
  25.         (@appId, @appName)  
  26.           
  27.         IF @@ERROR = 2627   
  28.         BEGIN  
  29.             DECLARE @dupApp tAppName  
  30.           
  31.             SELECT @dupApp = RTRIM(AppName)  
  32.             FROM [ASPState].dbo.ASPStateTempApplications   
  33.             WHERE AppId = @appId  
  34.               
  35.             RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.',   
  36.                         18, 1, @appName, @dupApp)  
  37.         END  
  38.     END  
  39.   
  40.     COMMIT  
  41. END  
  42.   
  43. RETURN 0  

 

  好了,如今咱们能够测试一下了,在一个站点中给Session赋个值,而后在另外一个站点中取一下,是否是能够取出来呢,若是能够,那么恭喜你,你已经实现了Session共享,应用到你的系统中吧。

 
0
相关文章
相关标签/搜索