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

  开发环境:WindowsXP、VS2005、.NET Framework 2.0、SQL Server 2000

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

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

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

  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表

ASPStateTempSessions表

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

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

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

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

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

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

  好了,现在我们可以测试一下了,在一个站点中给Session赋个值,然后在另一个站点中取一下,是不是可以取出来呢,如果可以,那么恭喜你,你已经实现了Session共享,应用到你的系统中吧。

 
0

使用SQL Server保存Session状态,实现单点登录的更多相关文章

  1. SQL server数据库内置账户SA登录设置

    SQL server数据库内置账户SA登录不了   设置SQL Server数据库给sa设置密码的时候  提示18456 解决步骤:   第二步:右击sa,选择属性: 第三步:点击状态选项卡:勾选授予 ...

  2. 采用集成的Windows验证和使用Sql Server身份验证进行数据库的登录

    采用集成的Windows验证和使用Sql Server身份验证进行数据库的登录 1.集成的Windows身份验证语法范例 1 string constr = "server=.;databa ...

  3. 基于SpringBoot+Redis的Session共享与单点登录

    title: 基于SpringBoot+Redis的Session共享与单点登录 date: 2019-07-23 02:55:52 categories: 架构 author: mrzhou tag ...

  4. SQL Server账号密码(sa)登录失败 错误原因:18456

    (其实以前经常用的时候,都很简单,最近一段时间不用了,再一看发现都忘记的差不多了,还是写一篇博客吧,防止下一次再在这种问题上面浪费时间) 使用window登录 打开属性 打开安全性 选择SQL ser ...

  5. SessionStateMode之SQL Server共享session

    分布式应用首先要解决的是跨域的问题,解决session.frame.cookie的跨域是最基本的,然后才是负载均衡和性能优化,上面的不解决就没法往后面进行.上一博客主要是解决了frame跨域的问题,今 ...

  6. [ASP.NET]配置使用SQL Server保存会话状态

    会话状态是ASP.NET应用程序状态的其中一种,这种状态的特点是以用户为单位,每个会话对应一个用户,也就是说在该用户的整个访问过程,会话状态保存的数据都会持续保存于服务器的介质中,直到会话超时(即用户 ...

  7. .net用SQL Server进行session会话管理

    保存在内存中的session经常由于dll的变动导致丢失.有一种方法可以长期保存session,那就是session的SqlServer模式. ASP.NET允许将会话数据存储到一个数据库服务器中,方 ...

  8. SQL Server 保存不了修改后的表的解决方法

    客户端报错(配图): 出现问题环境:在新建一个表之后,又想添加一个字段保存表,提示错误. 解决方案:在SQL Server 2008R2 中 对于对于重新保存新建表系统默认设置为“阻止”,在对应设置解 ...

  9. sql server数据库可疑状态解决方法

    前段时间客户数据服务器断电,开机后发现数据库状态标记为可疑,可能是断电引起的数据库日志文件损坏,修复方法如下: 只有mdf文件,重建日志: --注:example为测试用数据库,相应的Example_ ...

随机推荐

  1. QT 使用QPainter 绘制图形 和 世界变换 world transform

    1. 绘制椭圆  饼状型 贝塞尔曲线 绘制图像重写方法 void paintEvent(QPaintEvent *event)即可. void Widget::paintEvent(QPaintEve ...

  2. org.apache.http.NoHttpResponseException: XX.XX.XX.XX:80 failed to respond

    解决: Finally I fix the issue and it is caused by buffer size. By default, buffer size of httpclient i ...

  3. jQuery ajax 标准写法及进度条绘制

    jQuery ajax 标准写法及进度条绘制 $.ajax({ url: "http://www.microsoft.com", //请求的url地址 dataType: &quo ...

  4. 6.0动态加载权限用PermissionGen

    ndroid 6.0 新增加了运行时的动态添加权限,在此介绍一个第三方库,PermissionGen,可以很方便简洁的增加 6.0权限 首先给大家上  PermissionGen 库地址:https: ...

  5. php:PHP解析xml的4种方法

    XML处理是开发过程中经常遇到的,PHP对其也有很丰富的支持,本文只是对其中某几种解析技术做简要说明,包括:Xml parser, SimpleXML, XMLReader, DOMDocument. ...

  6. 将一个jar包放到linux下定时执行

    将一个jar包放到linux下定时执行 1.在dbtodb文件夹下新建一个dbtodb.sh,脚本内容为: #!/bin/bash cd /usr/dbtodb/ java -jar dbtodb.j ...

  7. 【WPF】推荐一款拖拉缩放控件的DEMO

    引言 在CodeProject上有个实现了控件拖拉缩放的DEMO,界面很漂亮,里面对Thumb和Adorner运用得很精彩.我觉得,使用WPF的开发者都可以去学习一下.下面放出链接. WPF Diag ...

  8. java学习笔记 --- 多线程(多线程的创建方式)

    1.创建多线程方式1——继承Thread类. 步骤:  A:自定义类MyThread继承Thread类.  B:MyThread类里面重写run()? 为什么是run()方法呢? C:创建对象 D:启 ...

  9. git 远程库 创建私钥

    1.创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell(W ...

  10. PHP数据结构之实现单链表

    学习PHP中,学习完语法,开始尝试实现数据结构,今天实现单链表 <?php class node //节点的数据结构 { public $id; public $name; public $ne ...