单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
asp.net跨域单点登录分为:
1、跨子域单点登录。如 blog.a.com 和 info.a.com 这2个站点同属一个主域.a.com,实现跨子域单点登录很简单,可以利用cookie,设置Domain为”.a.com'即可,这里就不再赘叙。
2、完成跨域单点登录。如 www.a.com www.b.com 这2个站点之间实现共享一个身份验证系统,只需在一处地方登录,下面主要谈下这种方式的实现方法。
asp.net 跨域单点登录实现原理:
当用户第一次访问web应用系统1的时候,因为还没有登录,会被引导到认证中心进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,返回给用户一个认证的凭据;用户再访问别的web应用的时候就会将这个Token带上,作为自己认证的凭据,应用系统接受到请求之后会把Token送到认证中心进行效验,检查Token的合法性。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。所有应用系统共享一个身份认证系统。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志,返还给用户。另外,认证系统还应该对Token进行效验,判断其有效性。 所有应用系统能够识别和提取Token信息要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对Token进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
比如说,我现在有3个分站点和1个认证中心(总站)。当用户访问分站点的时候,分站点会发Token到验证中心进行验证。验证中心判断用户是否已经登录。如果未登录,则返回到验证中心登录入口进行登录,否之则返回Token验证到分站点,直接进入分站点。
如图所示:
上面是实现单点登录的原理图,下面介绍下如何用asp.net实现跨域单点登录:
一、新建网站 MasterSite,作为总站认证中心。配置web.config,采用form登录验证。配置如下:
<authentication mode=”Forms”><forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” PRotection=”All” path=”/” timeout=”120”></forms></authentication><authorization><!--拒绝所有匿名用户--><deny users=”?”/></authorization><authentication mode=”Forms”><forms name=”.AspxFormAuth” loginUrl=”Default.aspx” defaultUrl=”center.html” protection=”All” path=”/” timeout=”120”></forms></authentication><authorization><!--拒绝所有匿名用户--><deny users=”?”/></authorization>
添加Default.aspx页面,用来进行登录。代码如下:
HTML Code:
<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %><!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”><html xmlns=”http://www.w3.org/1999/xhtml” ><head runat=”server”><title>总站登录</title></head><body><form id=”form1” runat=”server”><div><asp:Login ID=”Login1” runat=”server” OnAuthenticate=”Login1_Authenticate” UserName=”test”></asp:Login></div></form></body></html><%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<!DOCTYPE html PUBLIC ”-//W3C//DTD XHTML 1.0 Transitional//EN” ”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” ><head runat=”server”><title>总站登录</title></head><body><form id=”form1” runat=”server”><div><asp:Login ID=”Login1” runat=”server” OnAuthenticate=”Login1_Authenticate” UserName=”test”></asp:Login></div></form></body></html>
Default.cs Code:
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Text;public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){if (!IsPostBack){SSORequest ssoRequest = new SSORequest();#region 验证 Post 过来的参数//--------------------------------// 请求注销if (!string.IsNullOrEmpty(Request[”Logout”])){Authentication.Logout();return;}//--------------------------------// 各独立站点标识if (string.IsNullOrEmpty(Request[”IASID”])){return;}else{ssoRequest.IASID = Request[”IASID”];}//--------------------------------// 时间戳if (string.IsNullOrEmpty(Request[”TimeStamp”])){return;}else{ssoRequest.TimeStamp = Request[”TimeStamp”];}//--------------------------------// 各独立站点的访问地址if (string.IsNullOrEmpty(Request[”AppUrl”])){return;}else{ssoRequest.AppUrl = Request[”AppUrl”];}//--------------------------------// 各独立站点的 Tokenif (string.IsNullOrEmpty(Request[”Authenticator”])){return;}else{ssoRequest.Authenticator = Request[”Authenticator”];}ViewState[”SSORequest”] = ssoRequest;#endregion//验证从分站发过来的Tokenif (Authentication.ValidateAPPToken(ssoRequest)){string userAccount = null;// 验证用户之前是否登录过//验证 EAC 认证中心的 Cookie,验证通过时获取用户登录账号if (Authentication.ValidateEACCookie(out userAccount)){ssoRequest.UserAccount = userAccount;//创建认证中心发往各分站的 Tokenif (Authentication.CreateEACToken(ssoRequest)){Post(ssoRequest);}}else{return;}}else{return;}}}//post请求void Post(SSORequest ssoRequest){PostService ps = new PostService();ps.Url = ssoRequest.AppUrl;ps.Add(”UserAccount”, ssoRequest.UserAccount);ps.Add(”IASID”, ssoRequest.IASID);ps.Add(”TimeStamp”, ssoRequest.TimeStamp);ps.Add(”AppUrl”, ssoRequest.AppUrl);ps.Add(”Authenticator”, ssoRequest.Authenticator);ps.Post();}/// <summary>/// 验证登录账号和密码是否正确/// </summary>/// <param name=”userName”>登录账号</param>/// <param name=”userPwd”>登录密码</param>/// <returns></returns>private bool ValidateUserInfo(string userName, string userPwd){//从数据库中读取,验证登录账号和密码//略...return true;}protected void Login1_Authenticate(object sender, AuthenticateEventArgs e){if (string.IsNullOrEmpty(Login1.UserName) || string.IsNullOrEmpty(Login1.PassWord)){Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=/”javascript/”><!--alert('用户名密码不能为空!');// --></mce:script>”);return;}else if (ValidateUserInfo(Login1.UserName, Login1.Password) == false){Page.RegisterClientScriptBlock(”Add”, ”<mce:script lanuage=/”Javascript/”><!--alert('用户名密码错误!');// --></mce:script>”);return;}else{session[”CurrUserName”] = Login1.UserName;Session.Timeout = 120;SSORequest ssoRequest = ViewState[”SSORequest”] as SSORequest;// 如果不是从各分站 Post 过来的请求,则默认登录主站if (ssoRequest == null){FormsAuthentication.SetAuthCookie(Login1.UserName, false);ssoRequest = new SSORequest();//主站标识IDssoRequest.IASID = ”00”;ssoRequest.AppUrl = ”SiteList.aspx”;ssoRequest.TimeStamp = DateTime.Now.ToString(”yyyy-MM-dd HH:mm”);ssoRequest.Authenticator = string.Empty;Response.Redirect(”SiteList.aspx”);}ssoRequest.UserAccount = Login1.UserName;//创建Tokenif (Authentication.CreateEACToken(ssoRequest)){string expireTime = DateTime.Now.AddHours(3).ToString(”yyyy-MM-dd HH:mm”);Authentication.CreatEACCookie(ssoRequest.UserAccount, ssoRequest.TimeStamp, expireTime);Post(ssoRequest);}}}}using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Text;
public partial class _Default : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){if (!IsPostBack){SSORequest ssoRequest = new SSORequest();
#region 验证 Post 过来的参数//--------------------------------// 请求注销if (!string.IsNullOrEmpty(Request[”Logout”])){Authentication.Logout();return;}//--------------------------------// 各独立站点标识if (string.IsNullOrEmpty(Request[”IASID”])){return;}else{ssoRequest.IASID = Request[”IASID”];}
//--------------------------------// 时间戳if (string.IsNullOrEmpty(Request[”TimeStamp”])){return;}else{ssoRequest.TimeStamp = Request[”TimeStamp”];}
/
新闻热点
疑难解答