ASP.NET 1.1 无 Cookie SessionID 重写

ASP.NET 无Cookie会话安全加固
本文介绍了一种ASP.NET中针对无Cookie会话的安全加固方法,通过自定义模块SecureSessionModule来确保每个客户端拥有独立且安全的会话。该方案利用客户端信息生成唯一标识符,并通过比对来防止会话数据被意外共享。
         浏览器的会话使用存储在 SessionID 属性中的唯一标识符进行标识。会话 ID 使 ASP.NET 应用程序能够将特定的浏览器与 Web 服务器上相关的会话数据和信息相关联。会话 ID 的值在浏览器和 Web 服务器间通过 Cookie 进行传输,如果指定了无 Cookie 会话,则通过 URL 进行传输。
         ASP.NET 通过自动在页的 URL 中插入唯一的会话 ID 来保持无 Cookie 会话状态。例如,下面的 URL 已被 ASP.NET 修改,以包含唯一的会话 ID lit3py55t21z5v55vlm25s55:
               http://www.example.com/s(lit3py55t21z5v55vlm25s55)/orderform.aspx
         如果一个包含无 Cookie SessionID 的链接被多个浏览器共享时(可能通过搜索引擎或其他程序),此行为可能导致对会话数据的意外共享。可以通过禁用会话标识符的回收来降低多个客户端共享会话数据的可能性。为此,将 sessionState 配置元素的 regenerateExpiredSessionId 属性设置为 true。这样,在使用已过期的会话 ID 发起无 Cookie 会话请求时,将生成一个新的会话 ID。
                                                                                                                               ——摘自  MSDN

         .NET2.0中我们已可以通过重写 SessionIDManager 类来改变SessionID 的生成机制和验证方法来防止会话数据的意外共享(即出现多个浏览器被识别为同一个会话,共用一个Session),可在.NET1.1中却没有相关的类让我们改变SessionID 的生成机制(封装死了 emsad.gif),但受 一篇文章的启发,我们可以在SessionID 生成之后对它进行处理 emsmile.gif。文章是老外写的,由于本人阅读能力有限,偶可没时间去看一大版唧唧歪歪的鹰文 emangel.gif,直接下了 代码来看。还好代码不算多,思路也很清晰,大概了解了他实现重写SessionID的原理,我改了下在无Cookie 会话中完美实现了。
ContractedBlock.gif ExpandedBlockStart.gif 相关代码
None.gifusing System;
None.gif
using System.Web;
None.gif
using System.Web.SessionState;
None.gif
using System.Web.Security;
None.gif
using System.Configuration;
None.gif
using System.Security.Cryptography;
None.gif
using System.Runtime.Serialization;
None.gif
using System.Globalization;
None.gif
using System.Text;
None.gif
None.gif
public class SecureSessionModule : IHttpModule
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
private static string _ValidationKey = null;
InBlock.gif
InBlock.gif    
public void Init (HttpApplication app)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
if (_ValidationKey == null)
InBlock.gif            _ValidationKey 
= GetValidationKey ();
InBlock.gif        app.AcquireRequestState
+=new EventHandler(app_AcquireRequestState);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
void app_AcquireRequestState (Object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        _ValidationKey
=GetValidationKey();//每天生成一个KEY提高安全性
InBlock.gif

InBlock.gif        HttpContext current  
= ((HttpApplication) sender).Context;
InBlock.gif
InBlock.gif        
//将处理后的SessionID存在Session["ASP.NET_SessionID"]中
InBlock.gif
        string sessionid = GetSession (current, "ASP.NET_SessionID");
InBlock.gif
InBlock.gif        
if (sessionid != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (sessionid.Length <= 24)
InBlock.gif                RedirectUrl(current);
InBlock.gif
InBlock.gif            
string id = sessionid.Substring (024);
InBlock.gif            
string mac1 = sessionid.Substring (24);
InBlock.gif
InBlock.gif            
string mac2 = GetSessionIDMac (id, current.Request.UserHostAddress, current.Request.UserAgent, _ValidationKey);
InBlock.gif
InBlock.gif            
// 用户客户端信息发生的变化,比对失败
InBlock.gif
            if (String.CompareOrdinal(mac1, mac2) != 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                RedirectUrl(current);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            RedirectUrl(current);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private void RedirectUrl(HttpContext current)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         
//重定向页面以重新生成新的SessionID
InBlock.gif
         current.Response.Redirect(current.Request.Url.ToString(),true);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private string GetValidationKey ()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
string key = DateTime.Now.ToShortDateString();
InBlock.gif
InBlock.gif        
return key;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private string GetSession (HttpContext current, string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
object id = FindSession(current.Session,name);
InBlock.gif        
if (id == null
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// 将用户客户端信息加密存储在Session中以便比对
InBlock.gif
            id= current.Session.SessionID+GetSessionIDMac (current.Session.SessionID, current.Request.UserHostAddress,
InBlock.gif                current.Request.UserAgent, _ValidationKey);
InBlock.gif            current.Session[name]  
= id;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
return id.ToString();
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private object FindSession (HttpSessionState session, string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return session[name];
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
private string GetSessionIDMac (string id, string ip, string agent, string key)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        StringBuilder builder 
= new StringBuilder (id, 512);        
InBlock.gif        builder.Append (ip);
InBlock.gif        builder.Append (agent);
InBlock.gif
InBlock.gif        
using (HMACSHA1 hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (key)))
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return Convert.ToBase64String (hmac.ComputeHash (
InBlock.gif                Encoding.UTF8.GetBytes (builder.ToString ())));
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif     
public void Dispose () dot.gif{}
ExpandedBlockEnd.gif}
相关配置如下:
None.gif < configuration >
None.gif  
< system .web >
None.gif    
< httpModules >
None.gif      
< add  name ="SecureSession"  type ="SecureSessionModule,SecureSessionModule"   />
None.gif    
</ httpModules >
None.gif  
</ system.web >
None.gif
</ configuration >
None.gif

       大家看了代码后就会知道,它实现的原理主要是因为不可能有相同IP电脑客户端同时访问一台服务器,当出现SessionID相同但他们客户端信息不同时就自动将后一个访问的客户端重定向以新建一个会话。 
     
       遗憾的是在WAP上应用时就有问题了,由于客户端信息没IP唯一标识(移动不给手机号信息了 emangry.gif),所以如果相同型号的手机访问时就无法区分,不知哪位高人有没更好的解决办法,还望不吝赐教 emsmilep.gif

题外话:工作忙,时间紧,抄得多,写得少,有问题,请留言。欢迎大家多交流沟通~~~

转载于:https://www.cnblogs.com/outman2008/archive/2007/02/25/655804.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值