Junky's IT Notebook

          統計

          留言簿(8)

          積分與排名

          WebSphere Studio

          閱讀排行榜

          評論排行榜

          關于單點認證的一個簡單實現(結合Form認證)(轉)

          最近在做一個無敵長的項目,從五一休假做到十一休假!有一個需求就是要求單點登陸(SSO)


          解決思路如下:

          請求認證的網站 :用一個HttpModule 截取所有請求,判斷HttpContext.User是不是Null,如為空,判斷Url上是不是有簽名過的認證信息, 如果有,判斷簽名信息是否有效,如果有效,將認證信息寫入Cookie中.認證完成

          認證的網站: 如果登陸頁Url中有要求認證的網址,判斷用戶是不是已授權,如果已授權,將用戶信息簽名,寫入Url中

          二個網站都使用的Form認證

          代碼
          請求認證網站,HttpMoudle如下

            1using System;
            2using System.Collections.Generic;
            3using System.Text;
            4using System.Web;
            5using System.Web.Security;
            6using System.Security.Principal;
            7
            8namespace SSO
            9{
           10    /// <summary>
           11    /// 單點認證的HttpModule
           12    /// </summary>

           13    public class SSOAuthenticateHttpModule:IHttpModule
           14    {
           15        public String ModuleName
           16        {
           17            get return "SSOAuthenticateHttpModule"; }
           18        }

           19
           20        IHttpModule 成員
          135    }

          136}

          137


          SSOClient 是一個助手類主要負責認證簽名,設置Cookie,從Url中分離出認證信息
           1using System;
           2using System.Collections.Generic;
           3using System.Text;
           4using System.Security.Cryptography;
           5using System.Security.Principal;
           6using System.Web;
           7using System.Web.Security;
           8
           9
          10namespace SSO
          11{
          12    internal class SSOClient
          13    {
          14        private static String PublicKey = "公鑰信息,我用的是RSA,你可以自己生成"
          15        internal static bool ValidataData(String data, String signedData)
          16        {
          17            try
          18            {
          19                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(512);
          20                RSA.FromXmlString(PublicKey);
          21
          22                UnicodeEncoding ByteConverter = new UnicodeEncoding();
          23
          24                SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
          25                return RSA.VerifyData(ByteConverter.GetBytes(data), new SHA1CryptoServiceProvider(), Convert.FromBase64String(signedData));
          26            }

          27            catch
          28            {
          29                return false;
          30            }

          31
          32        }

          33
          34        internal static String SplitUserName(String data)
          35        {
          36            UnicodeEncoding ByteConverter = new UnicodeEncoding();
          37
          38            return data.Split('$')[0];
          39        }

          40
          41
          42        internal static String SplitToken(String data)
          43        {
          44            UnicodeEncoding ByteConverter = new UnicodeEncoding();
          45
          46
          47            return data.Split('$')[1];
          48        }

          49
          50        internal static void SetAuthCookie(HttpContext context, String userName, String token, bool isPersistent)
          51        {
          52
          53
          54            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
          55            1// Ticket version
          56            userName, // Username associated with ticket
          57            DateTime.Now, // Date/time issued
          58            DateTime.Now.AddMinutes(30), // Date/time to expire
          59            isPersistent, // "true" for a persistent user cookie
          60            token, // User-data, in this case the roles
          61            FormsAuthentication.FormsCookiePath);// Path cookie valid for
          62
          63            // Encrypt the cookie using the machine key for secure transport
          64            string hash = FormsAuthentication.Encrypt(ticket);
          65
          66            HttpCookie cookie = new HttpCookie(
          67               FormsAuthentication.FormsCookieName, // Name of auth cookie
          68               hash); // Hashed ticket
          69
          70            // Set the cookie's expiration time to the tickets expiration time
          71            if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
          72
          73            // Add the cookie to the list for outgoing response
          74            context.Response.Cookies.Add(cookie);
          75        }

          76
          77
          78    }

          79}

          80

          被認證的網站的WebConfig文件
          <?xml version="1.0"?>
          <!-- 
              注意: 除了手動編輯此文件以外,您還可以使用 
              Web 管理工具來配置應用程序的設置。可以使用 Visual Studio 中的
               “網站”->“Asp.Net 配置”選項。
              設置和注釋的完整列表在 
              machine.config.comments 中,該文件通常位于 
              \Windows\Microsoft.Net\Framework\v2.x\Config 中
          -->
          <configuration>
              
          <appSettings/>
              
          <connectionStrings/>
              
          <system.web>
                  
          <!-- 
                      設置 compilation debug="true" 將調試符號插入
                      已編譯的頁面中。但由于這會 
                      影響性能,因此只在開發過程中將此值 
                      設置為 true。
                  
          -->
                  
          <compilation debug="true">
                      
          <assemblies>
                          
          <add assembly="System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies></compilation>
                  
          <!--
                      通過 <authentication> 節可以配置 ASP.NET 使用的 
                      安全身份驗證模式,
                      以標識傳入的用戶。 
                  
          -->
              
          <authentication mode="Forms">
                
          <forms loginUrl="http://localhost/TestSSOServer/Default.aspx" name=".ASPXFORMSAUTH" protection="All" path="/" timeout="30" enableCrossAppRedirects="true"/>
              
          </authentication>
                
                  
          <!--<authorization>
                      <deny users="?"/>
                  </authorization>
          -->
                      
                  
                  
          <httpModules>
                      
          <add name="SSOAuthenticateHttpModule" type="SSO.SSOAuthenticateHttpModule"/>
                  
          </httpModules>
                  
          <!--
                      如果在執行請求的過程中出現未處理的錯誤,
                      則通過 <customErrors> 節可以配置相應的處理步驟。具體說來,
                      開發人員通過該節可以配置
                      要顯示的 html 錯誤頁
                      以代替錯誤堆棧跟蹤。

                  <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
                      <error statusCode="403" redirect="NoAccess.htm" />
                      <error statusCode="404" redirect="FileNotFound.htm" />
                  </customErrors>
                  
          -->
              
          </system.web>
          </configuration>


          認證網站,比較簡單,有一個負責登陸的頁面,我就在上面放了一個Button和一個TxtBox
           1using System;
           2using System.Data;
           3using System.Configuration;
           4using System.Web;
           5using System.Web.Security;
           6using System.Web.UI;
           7using System.Web.UI.WebControls;
           8using System.Web.UI.WebControls.WebParts;
           9using System.Web.UI.HtmlControls;
          10
          11public partial class _Default : System.Web.UI.Page 
          12{
          13    protected void Page_Load(object sender, EventArgs e)
          14    {
          15        if (!Page.IsPostBack)
          16        {   
          17            //判斷是不是已認證通過--這里只是簡單寫了,具體你是怎么認證的,就怎么寫
          18            if (Request.IsAuthenticated)
          19            {
          20                //回到請求認證的網站;
          21                ReturnUrl();
          22            }

          23        
          24        }

          25        
          26    }

          27    protected void Button1_Click(object sender, EventArgs e)
          28    {
          29        FormsAuthentication.SetAuthCookie(TextBox1.Text,false);
          30
          31        ReturnUrl();
          32
          33    }

          34
          35    /// <summary>
          36    /// 取得認證信息
          37    /// </summary>
          38    /// <returns></returns>

          39    private String getAuthInfo()
          40    {
          41        String userName = User.Identity.Name;
          42        String tokenValue = "這是一些附加信息,你可以寫入角色什么的";//在我的應用中,我寫的是一個Token
          43        String time = System.DateTime.Now.ToString();
          44
          45        String v = userName + "$" + tokenValue ;
          46
          47        return v;
          48
          49
          50    }

          51
          52    /// <summary>
          53    /// 返回請求認證的網站
          54    /// </summary>

          55    private void ReturnUrl()
          56    {
          57     
          58        String strUrl = Request.QueryString["site"];
          59
          60        if (String.IsNullOrEmpty(strUrl))
          61        {
          62            return;
          63        }

          64
          65        strUrl = HttpUtility.UrlDecode(strUrl);
          66
          67        //取得認證信息
          68        String data = getAuthInfo();
          69
          70        寫入簽名信息
          84
          85        Response.Redirect(strUrl);
          86  
          87    
          88    }

          89}

          90


          認證助手類
           1using System;
           2using System.Collections.Generic;
           3using System.Text;
           4using System.Security.Cryptography;
           5
           6namespace SSO
           7{
           8    public class SSOServer
           9    {
          10        private static String PrivateKey = "私鑰信息,這個很重要,";
          11        
          12        /// <summary>
          13        /// 簽 名用戶信息
          14        /// </summary>
          15        /// <param name="data"></param>
          16        /// <returns></returns>

          17        public static String SignatueData(String data)
          18        {
          19            try
          20            {
          21                //Create a UnicodeEncoder to convert between byte array and string.
          22                UnicodeEncoding ByteConverter = new UnicodeEncoding();
          23
          24                byte[] dataToSignatue = ByteConverter.GetBytes(data);
          25
          26                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(512);
          27                RSA.FromXmlString(PrivateKey);
          28
          29                String SignadString = Convert.ToBase64String(RSA.SignData(dataToSignatue, new SHA1CryptoServiceProvider()));
          30                return SignadString;
          31
          32            }

          33            catch
          34            {
          35                return String.Empty;
          36            }

          37        }

          38        //把一個字符串Base64編碼
          39        public static String Base64String(String data)
          40        {
          41            try
          42            {
          43                //Create a UnicodeEncoder to convert between byte array and string.
          44                UnicodeEncoding ByteConverter = new UnicodeEncoding();
          45
          46                byte[] dataToBase = ByteConverter.GetBytes(data);
          47
          48                return Convert.ToBase64String(dataToBase);
          49            }

          50            catch
          51            {
          52                return String.Empty;
          53            }

          54            
          55        }

          56
          57    }

          58}

          59

          posted on 2007-05-21 09:32 junky 閱讀(528) 評論(0)  編輯  收藏 所屬分類: security

          主站蜘蛛池模板: 沈丘县| 原阳县| 鄂温| 深水埗区| 定陶县| 玛曲县| 江源县| 兴城市| 合江县| 汕尾市| 集安市| 秦安县| 湛江市| 响水县| 沙河市| 岑巩县| 扎鲁特旗| 乐亭县| 南漳县| 平武县| 盐山县| 商丘市| 腾冲县| 农安县| 海宁市| 镇平县| 武陟县| 开封县| 浦城县| 佛坪县| 南郑县| 天祝| 旬阳县| 会同县| 依兰县| 崇礼县| 清水县| 富裕县| 阿克陶县| 赤水市| 永嘉县|