码迷,mamicode.com
首页 > Web开发 > 详细

asp.net 跨域单点登录 【转】

时间:2014-10-13 22:12:07      阅读:674      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   io   os   ar   java   

关键字:单点登录   跨域    跨域单点登录

源代码下载:http://download.csdn.net/source/1571879 

 

单点登录Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

asp.net跨域单点登录分为:

1、跨子域单点登录。如 blog.a.com 和 info.a.com 这2个站点同属一个主域.a.com,实现跨子域单点登录很简单,可以利用cookie,设置Domain为".a.com‘即可,这里就不再赘叙。

2、完成跨域单点登录。如 http://www.a.com/   http://www.b.com/ 这2个站点之间实现共享一个身份验证系统,只需在一处地方登录,下面主要谈下这种方式的实现方法。 

 

 

asp.net 跨域单点登录实现原理:
当用户第一次访问web应用系统1的时候,因为还没有登录,会被引导到认证中心进行登录;根据用户提供的登录信息,认证系统进行身份效验,如果通过效验,返回给用户一个认证的凭据;用户再访问别的web应用的时候就会将这个Token带上,作为自己认证的凭据,应用系统接受到请求之后会把Token送到认证中心进行效验,检查Token的合法性。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。所有应用系统共享一个身份认证系统。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志,返还给用户。另外,认证系统还应该对Token进行效验,判断其有效性。 所有应用系统能够识别和提取Token信息要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对Token进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。

比如说,我现在有3个分站点和1个认证中心(总站)。当用户访问分站点的时候,分站点会发Token到验证中心进行验证。验证中心判断用户是否已经登录。如果未登录,则返回到验证中心登录入口进行登录,否之则返回Token验证到分站点,直接进入分站点。

如图所示:

bubuko.com,布布扣

 

上面是实现单点登录的原理图,下面介绍下如何用asp.net实现跨域单点登录:

一、新建网站 MasterSite,作为总站认证中心。配置web.config,采用form登录验证。       配置如下:

1.<authentication mode="Forms">  
2.  <forms name=".AspxFormAuth" loginUrl="Default.aspx" defaultUrl="center.html" protection="All" path="/" timeout="120">  
3.  </forms>  
4.</authentication>  
5.<authorization>  
6.    <!--拒绝所有匿名用户-->  
7.    <deny users="?"/>  
8.</authorization>  

添加Default.aspx页面,用来进行登录。代码如下:    

     HTML Code:

1.<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>   
2.  
3.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">   
4.  
5.<html xmlns="http://www.w3.org/1999/xhtml" >   
6.<head runat="server">   
7.    <title>总站登录</title>   
8.</head>   
9.<body>   
10.    <form id="form1" runat="server">   
11.    <div>   
12.        <asp:Login ID="Login1" runat="server" OnAuthenticate="Login1_Authenticate" UserName="test">   
13.        </asp:Login>   
14.    </div>   
15.    </form>   
16.</body>   
17.</html>  

Default.cs Code: 

1.using System;   
2.using System.Data;   
3.using System.Configuration;   
4.using System.Web;   
5.using System.Web.Security;   
6.using System.Web.UI;   
7.using System.Web.UI.WebControls;   
8.using System.Web.UI.WebControls.WebParts;   
9.using System.Web.UI.HtmlControls;   
10.using System.Text;   
11.  
12.public partial class _Default : System.Web.UI.Page    
13.{   
14.    protected void Page_Load(object sender, EventArgs e)   
15.    {   
16.        if (!IsPostBack)   
17.        {   
18.            SSORequest ssoRequest = new SSORequest();  
19. 
20. 
21.            #region 验证 Post 过来的参数   
22.            //--------------------------------   
23.            // 请求注销   
24.            if (!string.IsNullOrEmpty(Request["Logout"]))   
25.            {   
26.                Authentication.Logout();   
27.                return;   
28.            }   
29.            //--------------------------------   
30.            // 各独立站点标识   
31.            if (string.IsNullOrEmpty(Request["IASID"]))   
32.            {   
33.                return;   
34.            }   
35.            else  
36.            {   
37.                ssoRequest.IASID = Request["IASID"];   
38.            }   
39.  
40.            //--------------------------------   
41.            // 时间戳   
42.            if (string.IsNullOrEmpty(Request["TimeStamp"]))   
43.            {   
44.                return;   
45.            }   
46.            else  
47.            {   
48.                ssoRequest.TimeStamp = Request["TimeStamp"];   
49.            }   
50.  
51.            //--------------------------------   
52.            // 各独立站点的访问地址   
53.            if (string.IsNullOrEmpty(Request["AppUrl"]))   
54.            {   
55.                return;   
56.            }   
57.            else  
58.            {   
59.                ssoRequest.AppUrl = Request["AppUrl"];   
60.            }   
61.  
62.            //--------------------------------   
63.            // 各独立站点的 Token   
64.            if (string.IsNullOrEmpty(Request["Authenticator"]))   
65.            {   
66.                return;   
67.            }   
68.            else  
69.            {   
70.                ssoRequest.Authenticator = Request["Authenticator"];   
71.            }   
72.  
73.            ViewState["SSORequest"] = ssoRequest;  
74. 
75.            #endregion   
76.  
77.  
78.            //验证从分站发过来的Token   
79.            if (Authentication.ValidateAppToken(ssoRequest))   
80.            {   
81.                string userAccount = null;   
82.  
83.                // 验证用户之前是否登录过   
84.                //验证 EAC 认证中心的 Cookie,验证通过时获取用户登录账号   
85.                if (Authentication.ValidateEACCookie(out userAccount))   
86.                {   
87.                    ssoRequest.UserAccount = userAccount;   
88.  
89.                    //创建认证中心发往各分站的 Token   
90.                    if (Authentication.CreateEACToken(ssoRequest))   
91.                    {   
92.                        Post(ssoRequest);   
93.                    }   
94.                }   
95.                else  
96.                {   
97.                    return;   
98.                }   
99.            }   
100.            else  
101.            {   
102.                return;   
103.            }   
104.        }   
105.    }   
106.  
107.  
108.    //post请求   
109.    void Post(SSORequest ssoRequest)   
110.    {   
111.        PostService ps = new PostService();   
112.  
113.        ps.Url = ssoRequest.AppUrl;   
114.  
115.        ps.Add("UserAccount", ssoRequest.UserAccount);   
116.        ps.Add("IASID", ssoRequest.IASID);   
117.        ps.Add("TimeStamp", ssoRequest.TimeStamp);   
118.        ps.Add("AppUrl", ssoRequest.AppUrl);   
119.        ps.Add("Authenticator", ssoRequest.Authenticator);   
120.  
121.        ps.Post();   
122.    }   
123.  
124.    /// <summary>   
125.    /// 验证登录账号和密码是否正确   
126.    /// </summary>   
127.    /// <param name="userName">登录账号</param>   
128.    /// <param name="userPwd">登录密码</param>   
129.    /// <returns></returns>   
130.    private bool ValidateUserInfo(string userName, string userPwd)   
131.    {   
132.        //从数据库中读取,验证登录账号和密码   
133.        //略...   
134.        return true;   
135.    }   
136.  
137.    protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)   
138.    {   
139.        if (string.IsNullOrEmpty(Login1.UserName) || string.IsNullOrEmpty(Login1.Password))   
140.        {   
141.            Page.RegisterClientScriptBlock("Add", "<mce:script lanuage=\"javascript\"><!--   
142.alert(用户名密码不能为空!);   
143.// --></mce:script>");   
144.            return;   
145.        }   
146.        else if (ValidateUserInfo(Login1.UserName, Login1.Password) == false)   
147.        {   
148.            Page.RegisterClientScriptBlock("Add", "<mce:script lanuage=\"javascript\"><!--   
149.alert(用户名密码错误!);   
150.// --></mce:script>");   
151.            return;   
152.        }   
153.        else  
154.        {   
155.            Session["CurrUserName"] = Login1.UserName;   
156.            Session.Timeout = 120;   
157.  
158.            SSORequest ssoRequest = ViewState["SSORequest"] as SSORequest;   
159.  
160.            // 如果不是从各分站 Post 过来的请求,则默认登录主站   
161.            if (ssoRequest == null)   
162.            {   
163.                FormsAuthentication.SetAuthCookie(Login1.UserName, false);   
164.  
165.                ssoRequest = new SSORequest();   
166.                //主站标识ID   
167.                ssoRequest.IASID = "00";   
168.                ssoRequest.AppUrl = "SiteList.aspx";   
169.                ssoRequest.TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm");   
170.                ssoRequest.Authenticator = string.Empty;   
171.  
172.                Response.Redirect("SiteList.aspx");   
173.            }   
174.            ssoRequest.UserAccount = Login1.UserName;   
175.  
176.            //创建Token   
177.            if (Authentication.CreateEACToken(ssoRequest))   
178.            {   
179.                string expireTime = DateTime.Now.AddHours(3).ToString("yyyy-MM-dd HH:mm");   
180.  
181.                Authentication.CreatEACCookie(ssoRequest.UserAccount, ssoRequest.TimeStamp, expireTime);   
182.  
183.                Post(ssoRequest);   
184.            }   
185.  
186.        }   
187.    }   
188.  
189.       
190.}  

代码说明:验证分站post过来的Token请求,如果用户已经登录,则创建认证中心发往各分站的 Token验证,转向分站,否之则返回登录。若是直接登录主站则转向站点选择页面sitelist.aspx,选择你要登录的分站点。
如图:

bubuko.com,布布扣

bubuko.com,布布扣

二、新建站点1,代码如下:

HTML Code:

1.<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>   
2.  
3.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">   
4.  
5.<html xmlns="http://www.w3.org/1999/xhtml" >   
6.<head runat="server">   
7.    <title> 站点一</title>   
8.</head>   
9.<body>   
10.    <form id="form1" runat="server">   
11.    <div>   
12.        <br />   
13.        <br />   
14.        <asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click">返回主站</asp:LinkButton>   
15.             
16.        <asp:LinkButton ID="LinkButton2" runat="server" OnClick="LinkButton2_Click">注销登录</asp:LinkButton></div>   
17.    </form>   
18.</body>   
19.</html>  

Default.cs code: 

1.using System;   
2.using System.Data;   
3.using System.Configuration;   
4.using System.Web;   
5.using System.Web.Security;   
6.using System.Web.UI;   
7.using System.Web.UI.WebControls;   
8.using System.Web.UI.WebControls.WebParts;   
9.using System.Web.UI.HtmlControls;   
10.using System.Text;   
11.  
12.public partial class _Default : System.Web.UI.Page    
13.{   
14.    protected void Page_Load(object sender, EventArgs e)   
15.    {   
16.        if (!IsPostBack)   
17.        {  
18.            #region SSO 部分代码   
19.            SSORequest ssoRequest = new SSORequest();   
20.  
21.            if (string.IsNullOrEmpty(Request["IASID"]))   
22.            {   
23.                ssoRequest.IASID = "01";   
24.                ssoRequest.TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm");   
25.                ssoRequest.AppUrl = Request.Url.ToString();   
26.                Authentication.CreateAppToken(ssoRequest);   
27.  
28.                Post(ssoRequest);   
29.            }   
30.            else if (!string.IsNullOrEmpty(Request["IASID"])   
31.                && !string.IsNullOrEmpty(Request["TimeStamp"])   
32.                && !string.IsNullOrEmpty(Request["AppUrl"])   
33.                && !string.IsNullOrEmpty(Request["UserAccount"])   
34.                && !string.IsNullOrEmpty(Request["Authenticator"]))   
35.            {   
36.                ssoRequest.IASID = Request["IASID"];   
37.                ssoRequest.TimeStamp = Request["TimeStamp"];   
38.                ssoRequest.AppUrl = Request["AppUrl"];   
39.                ssoRequest.UserAccount = Request["UserAccount"];   
40.                ssoRequest.Authenticator = Request["Authenticator"];   
41.  
42.                if (Authentication.ValidateEACToken(ssoRequest))   
43.                {   
44.                    //从数据库中获取UserId   
45.                    Session["CurrUserName"] = Request["UserAccount"];   
46.                    Session.Timeout = 120;   
47.                    FormsAuthentication.SetAuthCookie(Request["UserAccount"], false);   
48.                    Response.Write(string.Format("{0},您好!欢迎来到site1,  >> 访问<a href="\" mce_href="\""http://localhost/Site2/Default.aspx\">site2</a>",ssoRequest.UserAccount));   
49.                }   
50.            }   
51.  
52.            ViewState["SSORequest"] = ssoRequest;  
53. 
54.            #endregion   
55.        }   
56.    }   
57.  
58.    void Post(SSORequest ssoRequest)   
59.    {   
60.        PostService ps = new PostService();   
61.        //认证中心(主站)地址   
62.        string EACUrl = "http://localhost/MasterSite/Default.aspx";   
63.        ps.Url = EACUrl;   
64.        //ps.Add("UserAccount", ssoRequest.UserAccount);   
65.        ps.Add("IASID", ssoRequest.IASID);   
66.        ps.Add("TimeStamp", ssoRequest.TimeStamp);   
67.        ps.Add("AppUrl", ssoRequest.AppUrl);   
68.        ps.Add("Authenticator", ssoRequest.Authenticator);70.        ps.Post();   
71.    }   
72.  
73.  
74.    //注销登录   
75.    protected void LinkButton2_Click(object sender, EventArgs e)   
76.    {   
77.        FormsAuthentication.SignOut();   
78.  
79.        SSORequest ssoRequest = new SSORequest();   
80.  
81.        ssoRequest.IASID = "01";   
82.        ssoRequest.TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm");   
83.        ssoRequest.AppUrl = Request.Url.ToString();   
84.  
85.        Authentication.CreateAppToken(ssoRequest);   
86.  
87.        PostService ps = new PostService();   
88.  
89.        //认证中心(主站)地址   
90.        string EACUrl = "http://localhost/MasterSite/Default.aspx";   
91.        ps.Url = EACUrl;   
92.  
93.        ps.Add("IASID", ssoRequest.IASID);   
94.        ps.Add("TimeStamp", ssoRequest.TimeStamp);   
95.        ps.Add("AppUrl", ssoRequest.AppUrl);   
96.        ps.Add("Authenticator", ssoRequest.Authenticator);   
97.  
98.        ps.Add("Logout", "true");   
99.  
100.        ps.Post();   
101.    }   
102.  
103.    //返回主站   
104.    protected void LinkButton1_Click(object sender, EventArgs e)   
105.    {   
106.        if (Session["CurrUserName"] != null)   
107.        {   
108.            Response.Redirect("http://localhost/MasterSite/SiteList.aspx");   
109.        }   
110.    }   
111.}  

配置web.config 

1.<authentication mode="Forms">   
2.            <forms name=".AspxFormAuth" loginUrl="Default.aspx" defaultUrl="center.html" protection="All" path="/" timeout="60">   
3.            </forms>   
4.        </authentication>   
5.        <authorization>   
6.            <!--拒绝所有匿名用户-->   
7.            <deny users="?"/>   
8.        </authorization>  

三、同二一样,新建站点Site2,代码如下:

1.using System;   
2.using System.Data;   
3.using System.Configuration;   
4.using System.Web;   
5.using System.Web.Security;   
6.using System.Web.UI;   
7.using System.Web.UI.WebControls;   
8.using System.Web.UI.WebControls.WebParts;   
9.using System.Web.UI.HtmlControls;   
10.  
11.public partial class _Default : System.Web.UI.Page   
12.{   
13.    protected void Page_Load(object sender, EventArgs e)   
14.    {   
15.        if (!IsPostBack)   
16.        {  
17.            #region SSO 部分代码   
18.            SSORequest ssoRequest = new SSORequest();   
19.  
20.            if (string.IsNullOrEmpty(Request["IASID"]))   
21.            {   
22.                ssoRequest.IASID = "02";   
23.                ssoRequest.TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm");   
24.                ssoRequest.AppUrl = Request.Url.ToString();   
25.                Authentication.CreateAppToken(ssoRequest);   
26.  
27.                Post(ssoRequest);   
28.            }   
29.            else if (!string.IsNullOrEmpty(Request["IASID"])   
30.                && !string.IsNullOrEmpty(Request["TimeStamp"])   
31.                && !string.IsNullOrEmpty(Request["AppUrl"])   
32.                && !string.IsNullOrEmpty(Request["UserAccount"])   
33.                && !string.IsNullOrEmpty(Request["Authenticator"]))   
34.            {   
35.                ssoRequest.IASID = Request["IASID"];   
36.                ssoRequest.TimeStamp = Request["TimeStamp"];   
37.                ssoRequest.AppUrl = Request["AppUrl"];   
38.                ssoRequest.UserAccount = Request["UserAccount"];   
39.                ssoRequest.Authenticator = Request["Authenticator"];   
40.  
41.                if (Authentication.ValidateEACToken(ssoRequest))   
42.                {   
43.                    Session["CurrUserName"] = Request["UserAccount"];   
44.                    Session.Timeout = 120;   
45.                    FormsAuthentication.SetAuthCookie(Request["UserAccount"], false);   
46.                    Response.Write(string.Format("{0},您好!欢迎来到site2,  >> 访问<a href="\" mce_href="\""http://localhost/Site1/Default.aspx\">site1</a>", ssoRequest.UserAccount));   
47.                }   
48.            }   
49.  
50.            ViewState["SSORequest"] = ssoRequest;  
51. 
52.            #endregion   
53.        }   
54.    }   
55.  
56.    void Post(SSORequest ssoRequest)   
57.    {   
58.        PostService ps = new PostService();   
59.        //认证中心(主站)地址   
60.        string EACUrl = "http://localhost/MasterSite/Default.aspx";   
61.        ps.Url = EACUrl;   
62.        //ps.Add("UserAccount", ssoRequest.UserAccount);   
63.        ps.Add("IASID", ssoRequest.IASID);   
64.        ps.Add("TimeStamp", ssoRequest.TimeStamp);   
65.        ps.Add("AppUrl", ssoRequest.AppUrl);   
66.        ps.Add("Authenticator", ssoRequest.Authenticator);   
67.  
68.        ps.Post();   
69.    }   
70.  
71.  
72.    //注销登录   
73.    protected void LinkButton2_Click(object sender, EventArgs e)   
74.    {   
75.        FormsAuthentication.SignOut();   
76.  
77.        SSORequest ssoRequest = new SSORequest();   
78.  
79.        ssoRequest.IASID = "02";   
80.        ssoRequest.TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm");   
81.        ssoRequest.AppUrl = Request.Url.ToString();   
82.  
83.        Authentication.CreateAppToken(ssoRequest);   
84.  
85.        PostService ps = new PostService();   
86.  
87.        //认证中心(主站)地址   
88.        string EACUrl = "http://localhost/MasterSite/Default.aspx";   
89.        ps.Url = EACUrl;   
90.  
91.        ps.Add("IASID", ssoRequest.IASID);   
92.        ps.Add("TimeStamp", ssoRequest.TimeStamp);   
93.        ps.Add("AppUrl", ssoRequest.AppUrl);   
94.        ps.Add("Authenticator", ssoRequest.Authenticator);   
95.  
96.        ps.Add("Logout", "true");   
97.  
98.        ps.Post();   
99.    }   
100.  
101.    //返回主站   
102.    protected void LinkButton1_Click(object sender, EventArgs e)   
103.    {   
104.        if (Session["CurrUserName"] != null)   
105.        {   
106.            Response.Redirect("http://localhost/MasterSite/SiteList.aspx");   
107.        }   
108.    }   
109.} 

对于tokent请求,tokent验证,需要对它进行加密、解密。

其它代码:

Authentication.cs

1.using System;   
2.using System.Data;   
3.using System.Configuration;   
4.using System.Web;   
5.using System.Web.Security;   
6.using System.Collections.Generic;   
7.using System.Text;   
8.  
9./// <summary>   
10./// 安全验证类   
11./// </summary>   
12.public class Authentication   
13.{   
14.    static readonly string cookieName = "EACToken";   
15.    static readonly string hashSplitter = "|";   
16.  
17.    public Authentication()   
18.    {   
19.    }   
20.  
21.    public static string GetAppKey(int appID)   
22.    {   
23.        //string cmdText = @"select * from ";   
24.        return string.Empty;   
25.    }   
26.  
27.    public static string GetAppKey()   
28.    {   
29.        return "22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70";   
30.    }   
31.  
32.    public static string GetAppIV()   
33.    {   
34.        return "1E7FA9231E7FA923";   
35.    }   
36.  
37.    /// <summary>   
38.    /// 取得加密服务   
39.    /// </summary>   
40.    /// <returns></returns>   
41.    static CryptoService GetCryptoService()   
42.    {   
43.        string key = GetAppKey();   
44.        string IV = GetAppIV();   
45.  
46.        CryptoService cs = new CryptoService(key, IV);   
47.        return cs;   
48.    }   
49.  
50.    /// <summary>   
51.    /// 创建各分站发往认证中心的 Token   
52.    /// </summary>   
53.    /// <param name="ssoRequest"></param>   
54.    /// <returns></returns>   
55.    public static bool CreateAppToken(SSORequest ssoRequest)   
56.    {   
57.        string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;   
58.        string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);   
59.        string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;   
60.        byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);   
61.  
62.        CryptoService cs = GetCryptoService();   
63.  
64.        byte[] encrypted;   
65.  
66.        if (cs.Encrypt(bToEncrypt, out encrypted))   
67.        {   
68.            ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted);   
69.  
70.            return true;   
71.        }   
72.        else  
73.        {   
74.            return false;   
75.        }   
76.    }   
77.  
78.  
79.    /// <summary>   
80.    /// 验证从各分站发送过来的 Token   
81.    /// </summary>   
82.    /// <param name="ssoRequest"></param>   
83.    /// <returns></returns>   
84.    public static bool ValidateAppToken(SSORequest ssoRequest)   
85.    {   
86.        string Authenticator = ssoRequest.Authenticator;   
87.  
88.        string OriginalAuthenticator = ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;   
89.        string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);   
90.        string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;   
91.        byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);   
92.  
93.        CryptoService cs = GetCryptoService();   
94.        byte[] encrypted;   
95.  
96.        if (cs.Encrypt(bToEncrypt, out encrypted))   
97.        {   
98.            return Authenticator == CryptoHelper.ToBase64String(encrypted);   
99.        }   
100.        else  
101.        {   
102.            return false;   
103.        }   
104.    }   
105.  
106.  
107.    /// <summary>   
108.    /// 创建认证中心发往各分站的 Token   
109.    /// </summary>   
110.    /// <param name="ssoRequest"></param>   
111.    /// <returns></returns>   
112.    public static bool CreateEACToken(SSORequest ssoRequest)   
113.    {   
114.        string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;   
115.        string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);   
116.        string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;   
117.        byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);   
118.  
119.        CryptoService cs = GetCryptoService();   
120.        byte[] encrypted;   
121.  
122.        if (cs.Encrypt(bToEncrypt, out encrypted))   
123.        {   
124.            ssoRequest.Authenticator = CryptoHelper.ToBase64String(encrypted);   
125.  
126.            return true;   
127.        }   
128.        else  
129.        {   
130.            return false;   
131.        }   
132.    }   
133.  
134.  
135.    /// <summary>   
136.    /// 验证从认证中心发送过来的 Token   
137.    /// </summary>   
138.    /// <param name="ssoRequest"></param>   
139.    /// <returns></returns>   
140.    public static bool ValidateEACToken(SSORequest ssoRequest)   
141.    {   
142.        string Authenticator = ssoRequest.Authenticator;   
143.  
144.        string OriginalAuthenticator = ssoRequest.UserAccount + ssoRequest.IASID + ssoRequest.TimeStamp + ssoRequest.AppUrl;   
145.        string AuthenticatorDigest = CryptoHelper.ComputeHashString(OriginalAuthenticator);   
146.        string sToEncrypt = OriginalAuthenticator + AuthenticatorDigest;   
147.        byte[] bToEncrypt = CryptoHelper.ConvertStringToByteArray(sToEncrypt);   
148.  
149.        string EncryCurrentAuthenticator = string.Empty;   
150.        CryptoService cs = GetCryptoService();   
151.        byte[] encrypted;   
152.  
153.        if (cs.Encrypt(bToEncrypt, out encrypted))   
154.        {   
155.            EncryCurrentAuthenticator = CryptoHelper.ToBase64String(encrypted);   
156.  
157.            return Authenticator == EncryCurrentAuthenticator;   
158.        }   
159.        else  
160.        {   
161.            return false;   
162.        }   
163.    }   
164.  
165.  
166.    /// <summary>   
167.    /// 创建 EAC 认证中心的 Cookie   
168.    /// </summary>   
169.    /// <param name="userAccount"></param>   
170.    /// <param name="timeStamp"></param>   
171.    /// <param name="expireTime"></param>   
172.    /// <param name="cookieValue"></param>   
173.    /// <returns></returns>   
174.    public static bool CreatEACCookie(string userAccount, string timeStamp, string expireTime)   
175.    {   
176.        string plainText = "UserAccount=" + userAccount + ";TimeStamp=" + timeStamp + ";ExpireTime=" + expireTime;   
177.        plainText += hashSplitter + CryptoHelper.ComputeHashString(plainText);   
178.  
179.        CryptoService cs = GetCryptoService();   
180.        byte[] encrypted;   
181.  
182.        if (cs.Encrypt(CryptoHelper.ConvertStringToByteArray(plainText), out encrypted))   
183.        {   
184.            string cookieValue = CryptoHelper.ToBase64String(encrypted);   
185.            SetCookie(cookieValue);   
186.  
187.            return true;   
188.        }   
189.        else  
190.        {   
191.            return false;   
192.        }   
193.    }   
194.  
195.    /// <summary>   
196.    /// 验证 EAC 认证中心的 Cookie,验证通过时获取用户登录账号   
197.    /// </summary>   
198.    /// <param name="userAccount">输出用户登录账号</param>   
199.    /// <returns></returns>   
200.    public static bool ValidateEACCookie(out string userAccount)   
201.    {   
202.        userAccount = string.Empty;   
203.        try  
204.        {   
205.  
206.            string cookieValue = GetCookie().Value;   
207.            byte[] toDecrypt = CryptoHelper.FromBase64String(cookieValue);   
208.            CryptoService cs = GetCryptoService();   
209.  
210.            string decrypted = string.Empty;   
211.            if (cs.Decrypt(toDecrypt, out decrypted))   
212.            {   
213.  
214.                string[] arrTemp = decrypted.Split(Convert.ToChar(hashSplitter));   
215.                string plainText = arrTemp[0];   
216.                string hashedText = arrTemp[1];   
217.  
218.                userAccount = plainText.Split(Convert.ToChar(";"))[0].Split(Convert.ToChar("="))[1];   
219.  
220.                return hashedText.Replace("\0", string.Empty) == CryptoHelper.ComputeHashString(plainText);   
221.  
222.            }   
223.            else  
224.            {   
225.                return false;   
226.            }   
227.        }   
228.        catch (Exception e)   
229.        {   
230.            return false;   
231.        }   
232.    }   
233.  
234.  
235.    public static void Logout()   
236.    {   
237.        HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Parse("1900-1-1");   
238.        HttpContext.Current.Response.Cookies[cookieName].Path = "/";   
239.    }   
240.  
241.    private static void SetCookie(string cookieValue)   
242.    {   
243.        HttpContext.Current.Response.Cookies[cookieName].Value = cookieValue;   
244.        HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Now.AddHours(24);   
245.        HttpContext.Current.Response.Cookies[cookieName].Path = "/";   
246.    }   
247.  
248.    private static HttpCookie GetCookie()   
249.    {   
250.        HttpCookie cookie = HttpContext.Current.Request.Cookies["EACToken"];   
251.        return cookie;   
252.    }   
253.} 

CryptoHelper.cs 

1.using System;   
2.using System.Collections.Generic;   
3.using System.Text;   
4.using System.Security.Cryptography;   
5.  
6.public class CryptoHelper   
7.{   
8.    /// <summary>   
9.    /// 复合 Hash:string --> byte[] --> hashed byte[] --> base64 string   
10.    /// </summary>   
11.    /// <param name="s"></param>   
12.    /// <returns></returns>   
13.    public static string ComputeHashString(string s)   
14.    {   
15.        return ToBase64String(ComputeHash(ConvertStringToByteArray(s)));   
16.    }   
17.  
18.  
19.    public static byte[] ComputeHash(byte[] buf)   
20.    {   
21.        //return ((HashAlgorithm)CryptoConfig.CreateFromName("SHA1")).ComputeHash(buf);   
22.        return SHA1.Create().ComputeHash(buf);   
23.  
24.    }   
25.  
26.    /// <summary>   
27.    /// //System.Convert.ToBase64String   
28.    /// </summary>   
29.    /// <param name="buf"></param>   
30.    /// <returns></returns>   
31.    public static string ToBase64String(byte[] buf)   
32.    {   
33.        return System.Convert.ToBase64String(buf);   
34.    }   
35.  
36.  
37.    public static byte[] FromBase64String(string s)   
38.    {   
39.        return System.Convert.FromBase64String(s);   
40.    }   
41.  
42.    /// <summary>   
43.    /// //Encoding.UTF8.GetBytes(s)   
44.    /// </summary>   
45.    /// <param name="s"></param>   
46.    /// <returns></returns>   
47.    public static byte[] ConvertStringToByteArray(String s)   
48.    {   
49.        return Encoding.UTF8.GetBytes(s);//gb2312   
50.    }   
51.  
52.  
53.    public static string ConvertByteArrayToString(byte[] buf)   
54.    {   
55.        //return System.Text.Encoding.GetEncoding("utf-8").GetString(buf);   
56.  
57.        return Encoding.UTF8.GetString(buf);   
58.    }   
59.  
60.  
61.    /// <summary>   
62.    /// 字节数组转换为十六进制字符串   
63.    /// </summary>   
64.    /// <param name="buf"></param>   
65.    /// <returns></returns>   
66.    public static string ByteArrayToHexString(byte[] buf)   
67.    {   
68.        StringBuilder sb = new StringBuilder();   
69.        for (int i = 0; i < buf.Length; i++)   
70.        {   
71.            sb.Append(buf[i].ToString("X").Length == 2 ? buf[i].ToString("X") : "0" + buf[i].ToString("X"));   
72.        }   
73.        return sb.ToString();   
74.    }   
75.  
76.    /// <summary>   
77.    /// 十六进制字符串转换为字节数组   
78.    /// </summary>   
79.    /// <param name="s"></param>   
80.    /// <returns></returns>   
81.    public static byte[] HexStringToByteArray(string s)   
82.    {   
83.        Byte[] buf = new byte[s.Length / 2];   
84.        for (int i = 0; i < buf.Length; i++)   
85.        {   
86.            buf[i] = (byte)(Char2Hex(s.Substring(i * 2, 1)) * 0x10 + Char2Hex(s.Substring(i * 2 + 1, 1)));   
87.        }   
88.        return buf;   
89.    }   
90.  
91.  
92.    private static byte Char2Hex(string chr)   
93.    {   
94.        switch (chr)   
95.        {   
96.            case "0":   
97.                return 0x00;   
98.            case "1":   
99.                return 0x01;   
100.            case "2":   
101.                return 0x02;   
102.            case "3":   
103.                return 0x03;   
104.            case "4":   
105.                return 0x04;   
106.            case "5":   
107.                return 0x05;   
108.            case "6":   
109.                return 0x06;   
110.            case "7":   
111.                return 0x07;   
112.            case "8":   
113.                return 0x08;   
114.            case "9":   
115.                return 0x09;   
116.            case "A":   
117.                return 0x0a;   
118.            case "B":   
119.                return 0x0b;   
120.            case "C":   
121.                return 0x0c;   
122.            case "D":   
123.                return 0x0d;   
124.            case "E":   
125.                return 0x0e;   
126.            case "F":   
127.                return 0x0f;   
128.        }   
129.        return 0x00;   
130.    }   
131.} 

CryptoService.cs  

1.using System;   
2.using System.Data;   
3.using System.Configuration;   
4.using System.Web;   
5.using System.Web.Security;   
6.using System.Web.UI;   
7.using System.Web.UI.WebControls;   
8.using System.Web.UI.WebControls.WebParts;   
9.using System.Web.UI.HtmlControls;   
10.using System.Text;   
11.using System.Security.Cryptography;   
12.using System.IO;   
13.  
14.public class CryptoService   
15.{   
16.    /// <summary>   
17.    /// 加密的密钥   
18.    /// </summary>   
19.    string sKey = "22362E7A9285DD53A0BBC2932F9733C505DC04EDBFE00D70";   
20.    string sIV = "1E7FA9231E7FA923";   
21.  
22.    byte[] byteKey;   
23.    byte[] byteIV;   
24.  
25.    /// <summary>   
26.    /// 加密向量   
27.    /// </summary>   
28.    static byte[] bIV ={ 1, 2, 3, 4, 5, 6, 7, 8 };   
29.  
30.    public CryptoService()   
31.    { }   
32.  
33.    public CryptoService(string key, string IV)   
34.    {   
35.        sKey = key;   
36.        sIV = IV;   
37.  
38.        byteKey = CryptoHelper.HexStringToByteArray(sKey);   
39.        byteIV = CryptoHelper.HexStringToByteArray(sIV);   
40.    }   
41.  
42.  
43.  
44.    /// <summary>   
45.    /// 将明文加密,返回密文   
46.    /// </summary>   
47.    /// <param name="Data">要加密的字串</param>   
48.    /// <returns></returns>   
49.    public byte[] Encrypt(string Data)   
50.    {   
51.        try  
52.        {   
53.            byte[] ret;   
54.  
55.            using (MemoryStream mStream = new MemoryStream())   
56.            using (CryptoStream cStream = new CryptoStream(mStream,   
57.                new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV),   
58.                CryptoStreamMode.Write))   
59.            {   
60.  
61.                byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data);   
62.  
63.                // Write the byte array to the crypto stream and flush it.   
64.                cStream.Write(toEncrypt, 0, toEncrypt.Length);   
65.                cStream.FlushFinalBlock();   
66.  
67.                // Get an array of bytes from the    
68.                // MemoryStream that holds the    
69.                // encrypted data.   
70.                ret = mStream.ToArray();   
71.  
72.            }   
73.  
74.            return ret;   
75.        }   
76.        catch (CryptographicException e)   
77.        {   
78.            //Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);   
79.            return null;   
80.        }   
81.  
82.    }   
83.  
84.  
85.    /// <summary>   
86.    /// 将明文加密,返回密文   
87.    /// </summary>   
88.    /// <param name="toEncrypt">明文</param>   
89.    /// <param name="encrypted">密文</param>   
90.    /// <returns></returns>   
91.    public bool Encrypt(byte[] toEncrypt, out byte[] encrypted)   
92.    {   
93.        encrypted = null;   
94.        try  
95.        {   
96.            // Create a new MemoryStream using the passed    
97.            // array of encrypted data.   
98.            // Create a CryptoStream using the MemoryStream    
99.            // and the passed key and initialization vector (IV).   
100.            using (MemoryStream mStream = new MemoryStream())   
101.            using (CryptoStream cStream = new CryptoStream(mStream,   
102.                new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV),   
103.                CryptoStreamMode.Write))   
104.            {   
105.  
106.                // Write the byte array to the crypto stream and flush it.   
107.                cStream.Write(toEncrypt, 0, toEncrypt.Length);   
108.                cStream.FlushFinalBlock();   
109.  
110.                // Get an array of bytes from the    
111.                // MemoryStream that holds the    
112.                // encrypted data.   
113.                encrypted = mStream.ToArray();   
114.            }   
115.  
116.            return true;   
117.        }   
118.        catch (CryptographicException e)   
119.        {   
120.            //Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);   
121.            return false;   
122.        }   
123.  
124.    }   
125.  
126.  
127.  
128.    /// <summary>   
129.    /// 将明文加密,返回 Base64 字符串   
130.    /// </summary>   
131.    /// <param name="Data"></param>   
132.    /// <returns></returns>   
133.    public string EncryptToString(string Data)   
134.    {   
135.        try  
136.        {   
137.            string base64String = string.Empty;   
138.  
139.            using (MemoryStream mStream = new MemoryStream())   
140.            using (CryptoStream cStream = new CryptoStream(mStream,   
141.                new TripleDESCryptoServiceProvider().CreateEncryptor(byteKey, byteIV),   
142.                CryptoStreamMode.Write))   
143.            {   
144.  
145.                byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data);   
146.  
147.                cStream.Write(toEncrypt, 0, toEncrypt.Length);   
148.                cStream.FlushFinalBlock();   
149.  
150.                byte[] ret = mStream.ToArray();   
151.  
152.                base64String = Convert.ToBase64String(ret);   
153.            }   
154.  
155.            return base64String;   
156.        }   
157.        catch (CryptographicException e)   
158.        {   
159.            return null;   
160.        }   
161.  
162.    }   
163.  
164.  
165.    /// <summary>   
166.    /// 将密文解密,返回明文   
167.    /// </summary>   
168.    /// <param name="Data">密文</param>   
169.    /// <returns>明文</returns>   
170.    public bool Decrypt(byte[] Data, out string decrypted)   
171.    {   
172.        decrypted = string.Empty;   
173.        try  
174.        {   
175.  
176.            using (MemoryStream msDecrypt = new MemoryStream(Data))   
177.            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt,   
178.                new TripleDESCryptoServiceProvider().CreateDecryptor(byteKey, byteIV),   
179.                CryptoStreamMode.Read))   
180.            {   
181.  
182.                byte[] fromEncrypt = new byte[Data.Length];   
183.  
184.                // Read the decrypted data out of the crypto stream   
185.                // and place it into the temporary buffer.   
186.                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);   
187.  
188.                decrypted = Encoding.UTF8.GetString(fromEncrypt);//new ASCIIEncoding().GetString(fromEncrypt);   
189.  
190.                return true;   
191.            }   
192.        }   
193.        catch (CryptographicException e)   
194.        {   
195.            return false;   
196.        }   
197.    }   
198.  
199.}  

PostService.cs

1.using System;   
2.using System.Collections.Generic;   
3.using System.Text;   
4.  
5.public class PostService   
6.{   
7.    private System.Collections.Specialized.NameValueCollection Inputs = new System.Collections.Specialized.NameValueCollection();   
8.    public string Url = "";   
9.    public string Method = "post";   
10.    public string FormName = "form1";   
11.  
12.    /// <summary>   
13.    /// 添加需要提交的名和值   
14.    /// </summary>   
15.    /// <param name="name"></param>   
16.    /// <param name="value"></param>   
17.    public void Add(string name, string value)   
18.    {   
19.        Inputs.Add(name, value);   
20.    }   
21.  
22.    /// <summary>   
23.    /// 以输出Html方式POST   
24.    /// </summary>   
25.    public void Post()   
26.    {   
27.        System.Web.HttpContext.Current.Response.Clear();   
28.  
29.        string html = string.Empty;   
30.  
31.        html += ("<html><head>");   
32.        html += (string.Format("</head><body onload=\"document.{0}.submit()\">", FormName));   
33.        html += (string.Format("<form name=\"{0}\" method=\"{1}\" action=\"{2}\" >", FormName, Method, Url));   
34.        try  
35.        {   
36.            for (int i = 0; i < Inputs.Keys.Count; i++)   
37.            {   
38.                html += (string.Format("<input name=\"{0}\" type=\"hidden\" value=\"{1}\">", Inputs.Keys[i], Inputs[Inputs.Keys[i]]));   
39.            }   
40.            html += ("</form>");   
41.            html += ("</body></html>");   
42.  
43.            System.Web.HttpContext.Current.Response.Write(html);   
44.            System.Web.HttpContext.Current.Response.End();   
45.        }   
46.        catch (Exception ee)   
47.        {   
48.            //   
49.        }   
50.    }   
51.}  

SSORequest.cs

1.using System;   
2.using System.Data;   
3.using System.Configuration;   
4.using System.Web;   
5.using System.Web.Security;   
6.using System.Web.UI;   
7.using System.Web.UI.WebControls;   
8.using System.Web.UI.WebControls.WebParts;   
9.using System.Web.UI.HtmlControls;   
10.  
11.[Serializable]   
12.public class SSORequest : MarshalByRefObject   
13.{   
14.    public string IASID;         //各独立站点标识ID   
15.    public string TimeStamp;     //时间戳   
16.    public string AppUrl;        //各独立站点的访问地址   
17.    public string Authenticator; //各独立站点的 Token   
18.  
19.    public string UserAccount;   //账号   
20.    public string Password;      //密码   
21.  
22.    public string IPAddress;     //IP地址   
23.  
24.    //为ssresponse对象做准备   
25.    public string ErrorDescription = "认证失败";   //用户认证通过,认证失败,包数据格式不正确,数据校验不正确   
26.    public int Result = -1;   
27.  
28.    public SSORequest()   
29.    {   
30.  
31.    }   
32.  
33.  
34.    /// <summary>   
35.    /// 获取当前页面上的SSORequest对象   
36.    /// </summary>   
37.    /// <param name="CurrentPage"></param>   
38.    /// <returns></returns>   
39.    public static SSORequest GetRequest(Page CurrentPage)   
40.    {   
41.        SSORequest request = new SSORequest();   
42.        request.IPAddress = CurrentPage.Request.UserHostAddress;   
43.        request.IASID = CurrentPage.Request["IASID"].ToString();// Request本身会Decode   
44.        request.UserAccount = CurrentPage.Request["UserAccount"].ToString();//this.Text   
45.        request.Password = CurrentPage.Request["Password"].ToString();   
46.        request.AppUrl = CurrentPage.Request["AppUrl"].ToString();   
47.        request.Authenticator = CurrentPage.Request["Authenticator"].ToString();   
48.        request.TimeStamp = CurrentPage.Request["TimeStamp"].ToString();   
49.        return request;   
50.    }   
51.}  

配置web.config

1.<authentication mode="Forms">   
2.            <forms name=".AspxFormAuth" loginUrl="Default.aspx" defaultUrl="center.html" protection="All" path="/" timeout="60">   
3.            </forms>   
4.        </authentication>   
5.        <authorization>   
6.            <!--拒绝所有匿名用户-->   
7.            <deny users="?"/>   
8.        </authorization>  

<authentication mode="Forms">
            <forms name=".AspxFormAuth" loginUrl="Default.aspx" defaultUrl="center.html" protection="All" path="/" timeout="60">
            </forms>
        </authentication>
        <authorization>
            <!--拒绝所有匿名用户-->
            <deny users="?"/>
        </authorization>

最后效果如下:登录总站后,各站点之间无需再登录,可以互相访问。

bubuko.com,布布扣

 

bubuko.com,布布扣

另外,注销登录后,访问站点1 http://localhost/Site1/Default.aspx ,会自动跳转到主站登录页面 http://localhost/MasterSite/Default.aspx ,同样访问站点2 http://localhost/Site2/Default.aspx 也会转到主站登录页面。从主站登录后,分别访问站点1和站点2。

在IIS配置虚拟目录MasterSite Site1 Site2,当然你也可以新建站点MasterSite Site1 Site2,修改hosts表 127.0.0.1      http://www.mastersite.com/

127.0.0.1      http://www.site1.com/

127.0.0.1      http://www.site2.com/

源代码下载:http://download.csdn.net/source/1571879 

asp.net 跨域单点登录 【转】

标签:des   style   blog   http   color   io   os   ar   java   

原文地址:http://www.cnblogs.com/shengfa/p/4023003.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!