关于sso 网页跳转 的代码.

 在我的上篇博客中,我介绍了网页跳转的sso 方案,http://www.cnblogs.com/jake1/archive/2013/04/28/sso_page.html                       

接下来,我把部分实现的代码也共享出来,供大家参考. 

首先,单点登录中心,我们以前做的项目,就把portal网站,作为单点登录的中心.

  单点登录,中心,通过实现Ihttphandle获取的.

View Code
  1   public class SsoHander : IHttpHandler
  2     {
  3         /// <summary>
  4         /// 您将需要在您网站的 web.config 文件中配置此处理程序,
  5         /// 并向 IIS 注册此处理程序,然后才能进行使用。有关详细信息,
  6         /// 请参见下面的链接: http://go.microsoft.com/?linkid=8101007
  7         /// </summary>
  8         #region IHttpHandler Members
  9 
 10         public bool IsReusable
 11         {
 12             // 如果无法为其他请求重用托管处理程序,则返回 false。
 13             // 如果按请求保留某些状态信息,则通常这将为 false。
 14             get { return false; }
 15         }
 16 
 17 
 18 
 19         public void ProcessRequest(HttpContext context)
 20         {
 21           
 22             bool isHttpsRequest = IsHttpsRequest(context);
 23 
 24             //在此写入您的处理程序实现。
 25             HttpRequest Request = context.Request;
 26             HttpResponse Response = context.Response;
 27             SPWeb web = SPContext.Current.Web;
 28             string appNo = System.IO.Path.GetFileNameWithoutExtension(Request.Url.AbsolutePath).ToLower();
 29             string url =context.Server.UrlEncode(Request["r"]);
 30             string loginUrl = Request["l"];
 31 
 32 
 33             if (web.CurrentUser != null)
 34             {
 35                 // Response.Write(web.CurrentUser.LoginName);
 36                 string userName = web.CurrentUser.Name;
 37                 userName = userName.Substring(userName.LastIndexOf('|') + 1);
 38 
 39 
 40                 // 检验该应用程序编码是否存在
 41                 System.Data.DataTable Appdb = SQLHelp.GetApplicationInfo(appNo);
 42                 if (Appdb == null || Appdb.Rows.Count == 0)
 43                 {
 44                     Response.Write("跳转地址有错误,请检查");
 45                     Response.End();
 46                 }
 47 
 48                 //写登录日志
 49                 SQLHelp.InsertLoginLog(userName, Request.UserHostAddress, appNo, true);
 50 
 51 
 52 
 53 
 54                 //如果不存在登录处理页,读取数据库默认的
 55                 if (string.IsNullOrEmpty(loginUrl))  loginUrl = Appdb.Rows[0]["LoginUrl"].ToString();
 56 
 57 
 58                 }
 59 
 60                 //查看应该系统是否是用的是ad用户
 61                 if (Convert.ToBoolean(Appdb.Rows[0]["IsAD"]) == true)
 62                 {
 63                  
 64                     object adPwd = SQLHelp.GetAdpassWord(userName);
 65                     userName = DESEncrypt.DesEncrypt(userName);
 66                     if (adPwd == null) Response.Write("ad用户错误,请联系管理员");                
 67 
 68                     string redirectUrl = string.Format("{0}?u={1}&p={2}&r={3}", loginUrl, context.Server.UrlEncode(userName), context.Server.UrlEncode(adPwd.ToString()), url);
 69                    // redirectUrl = context.Server.HtmlEncode(redirectUrl);
 70                     Response.Redirect(redirectUrl);
 71                 }
 72                 else
 73                 {
 74                     //非ad用户获取用户名
 75                     System.Data.DataTable appUserInfo = SQLHelp.GetAppAccount(userName, appNo);                  
 76  
 77                     //如果能在usermaping 表查到用户,就跳转登录页
 78                     if (appUserInfo != null&&appUserInfo.Rows.Count>0)
 79                     {
 80                         string u=context.Server.UrlEncode(appUserInfo.Rows[0]["userName"].ToString());
 81                         string p=context.Server.UrlEncode(appUserInfo.Rows[0]["PassWord"].ToString());
 82                         string redirectUrl = string.Format("{0}?u={1}&p={2}&r={3}", loginUrl,u ,p , url);
 83                         Response.Redirect(redirectUrl);
 84                  
 85                     }
 86                     else 
 87                     { //否则跳转用户usermaping表.
 88                         loginUrl = context.Server.UrlEncode(loginUrl);
 89                         string str = string.Format("/_layouts/ManageUserMapping.aspx?a={0}&l={1}&r={2}", appNo, loginUrl, url);
 90                         Response.Redirect(str);
 91                     }
 92                 }
 93 
 94             }
 95 
 96                 //如果没有登录,跳转登录页
 97             else
 98             {
 99 
100                 Response.Redirect("/_forms/default.aspx" );
101            
102             }
103         }
104 
105         #endregion
106     }

  然后,我们用.net,网站实现了一个基类.那个类通过重写oninit 函数,首先会 去检测改用户有没有登录,如果没有登录,将跳转到单点登录中心去获取登录的用户名和密码,获取后实现单点登录.登录完后就可以正常使用了.
 我们看看基类实现吧.

 

  protected override void OnInit(EventArgs e)
  {
   //检测是单点登录中心跳转回来的页面   
   string userName = HttpContext.Current.Request["u"];
            if (string.IsNullOrEmpty(userName) )
            {
               
                //没有登录,跳转到门户登录页 
                //string loginUrl = "http://" + Request.Url.Authority + Request.Url.AbsolutePath;
                string returnUrl = HttpContext.Current.Request.Url.AbsoluteUri;
                Session["rrrr"] = returnUrl;
                //特殊字符处理
                returnUrl = returnUrl.Replace("&", "_,_");
                string url = string.Format("{0}?r={1}&l={2}", SSOUrl, returnUrl, loginUrl);
                HttpContext.Current.Response.Redirect(url);
            }
            else  //登录处理,保存session
            {
                
                string userID = DESEncrypt.DesDecrypt(userName);
                //登录处理
                this.LoadUserInfo(userID);

                string r = HttpContext.Current.Request["r"];
                if (r != null)
                {
                    r = r.Replace("_,_", "&");
                    HttpContext.Current.Response.Redirect(r);
                }
                else
                {
                    if (Session["rrrr"] != null)
                        HttpContext.Current.Response.Redirect(Session["rrrr"].ToString());
                    else
                    {
                        HttpContext.Current.Response.Redirect(SSOUrl);
                    }
                }
              }
     }

     当时由于时间关系,这个安全性方面,还是有加强的地方.我们实现这方法一个最大好处.就是做了很好的封装性.这段代码是我们在基类里的,用了2年多,我还很多同事都还不知道我们在哪里实现单点登录的.
     对于其他java系统,实现的原理也是跟这个差不多.     好,下面我再介绍一下,这种方案的退出以及它的代码.

posted @ 2013-04-28 21:07  jake强  阅读(1787)  评论(4编辑  收藏  举报