现在越来越多的系统迫于压力以及提高性能,很多站点都是采用多站点分布式运行,例如腾讯、新浪的站点就分成很多个频道,各个频道有独立的域名,独立的IP来支撑,这样一来各个站点之间就出现了统一认证的问题,也就是需要用户在一个站点登录,其他站点都能用的,且退出之后,各个站点都不能用,形成对用户的统一管理,避免了各个子系统之间的功能冗余。
本文就作者自己的一些使用过的设计方法进行整理。使用过的方式主要两种,一是认证中心被动认证,二是认证中心主动认证,本文将介绍被动认证模式。
一、认证流程
主要的流程是,用户第一次访问系统A的页面a,当前系统(系统A)状态还没有登录,所以只能跳转到认证中心进行登录,登录之后,认证中心跳转回来站点A的页面a,该用户现在已经拥有了Token(Token由认证中心根据用户名以及登录时间生成,这个是唯一的字符串,每次生成都会不同),但是站点A不知道此Token是否合法,所以系统A自动跳转到认证中心,拿该Token进行验证,验证通过再跳转回来站点A,此时站点知道用户的Token合法,允许访问页面a。此种验证方法有个小问题就是,访问站点A的每个页面都需要到认证中心认证所拥有的Token是否合法(因为有可能用户会在其中一个子系统退出,退出后用户的旧Token为非法Token)
二、认证实现(C#,VS2008)
首先,建立认证中心的Web站点,页面机构如下:
子站点SubWebSite工程,页面结构如下:
修改一下上边的验证示意图,得到页面调用顺序示意图:
来看实现代码:
SubWebSite:Default.aspx
<form id="form1" runat="server">
<div>
通过了认证,登录的用户名为<%=Session["UserName"] %>
<asp:Button ID="btnSignOut" runat="server" Text="退出"
onclick="btnSignOut_Click" />
</div>
</form>
Default.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
//当前子系统登录,且没有从认证中心取得Token
if (Session["Token"] == null && Request.QueryString["Token"] == null)
ReSignIn();//需要重新登录
//Session和Url中都有Token
if (Request.QueryString["Token"] != null && Session["Token"] != null)
{
//Url中的Token和Session中的Token不一致,Token已经失效
string urlToken = Request.QueryString["Token"];
string sessionToken = Request.QueryString["Token"];
if (!urlToken.Equals(sessionToken))
{