单点登录

编辑
文档创建者:夏娃 (超级管理员 )     浏览次数:5263次     编辑次数:10次     最近更新:doreen0813 于 2017-11-30     

1、单点登录编辑

1.1 单点登录原理
所谓单点登录通常是指在多系统集成的时候,使用帐号登录一次,即可以登录所有的系统;避免多次登录的麻烦 ,使多系统集成在前端展示时是无缝的。其实现的方法有两种:一种是同时登录,一种是需要登录时登录;例如将BI集成到OA系统上,同时登录即在登录OA的时候,后台将获取的"username"、'password'传递到BI系统上,BI系统登录验证该"username"、"password",若验证通过则登录BI系统,此时即一次完成两个系统的登录。另一种方式是在登录完OA系统后,当有进入BI系统的需求时,如要查看BI分析模板,后台判断当需要登录时自动传递当前的'username"、"password'传递给BI系统进行登录验证,验证通过即可查看分析模板。两种方式只是登录BI系统的时间不同而已,都要经过两个步骤,一个是要获取''username'、'password',一个是要传递到BI系统中进行验证。从原理上看,只要能将获取的''username'、'password'传递到BI上,并登录验证成功,则单点登录就成功了。为保证两个系统的''username'、'password'的同一性,通常使用用户同步数据集的方式来实现。
注:通常用户的系统中会分为明文与密文。在从OA传递'username1'、'password1'到BI与BI从数据集同步过来的''username2'、'password2'进行匹配,当password同为明文或同为密文的时候,在同步数据集的时候无需设置加密方式;若OA传过来的是明文而BI同步过来的是密文,则需要设置加密方式,使OA传过来的明文进一次加密后再与BI中的password2匹配。(无论如何设置,一定要保证传递过来的password能通过BI中的password2匹配成功。)
当前BI提供了三种的单点登录设置方式:ajax方式、iframe方式、表单方式;ajax方式与iframe方式,可进行跨域单点登录即当两个系统不是在同一个服务器上布署时就要进行跨域单点登录。下面分别讲述这三者登录的设置方式。
1.2 ajax方式单点登录
ajax方式是通过在OA系统登录界面上添加ajax事件来完成传递'username'、'password'到BI进行登录验证。用户在OA系统上输入用户名密码后点击提交或登录按钮时,触发doSubmit(),通过ajax将用户名密码发送到BI系统进行验证,并且在验证成功时,触发html中的表单提交事件,实现BI的登录。由于使用了ajax,需要引入jquery.js,并且因为编码的问题,要对输入的用户名和密码进行cjkEncode编码,需要引入finereport.js,而FR的finereport.js中包含了jquery.js,所以只需要在head标签中引入finereport.js即可,无需再引入jquery.js。其代码如入:
<html>     <head>       <script type="text/javascript" src="ReportServer?op=emb&resource=finereport.js"></script>     <script type="text/javascript">       function doSubmit() {}
在function doSubmit()后的大括号将实现上述两个步骤“获取用户名及密码”“传递到BI中验证登录”
获取用户名及密码
获取用户名及密码,对输入的用户名和密码进行cjkEncode编码,代码如下:
    var username = FR.cjkEncode(document.getElementById("username").value); //获取输入的用户名       var password = FR.cjkEncode(document.getElementById("password").value);  //获取输入的参数   
其中document.getElementByld中的"username"、''password"是OA系统登录界面用户名、密码的文本框中输入值的参数名(实际参数的名称自行在登录界面上查找)。
传递用户名及密码并验证登录
添加ajex事件,设置要传递到的服务器的地址,设置跨域方式;使用date函数将获取的username及password赋给BI系统的用户名及密码的参数(BI4.0的用户名及密码的参数是'fr_username''fr_password');callback回调函数将参数返回后台并返回判断结果即验证登录,timeout超时时间定为5000ms;返回的结果验证成功:如果BI系统读取的"username"、''password"在后台验证通过,即进行跳转(可跳到index首页,也可直接指定到op=fs平台上);如果BI系统中未验证成功则显示“fail”;返回的结果未验证成功即"username"、''password"未传递到BI服务器上就显示“error”。其代码如下:
jQuery.ajax({        url:"http://localhost:37799/WebReport/ReportServer?op=fs_load&cmd=sso",//单点登录的报表服务器        dataType:"jsonp",//跨域采用jsonp方式        data:{"fr_username":username,"fr_password":password},        jsonp:"callback",        timeout:5000,//超时时间(单位:毫秒)        success:function(data) {               if (data.status === "success") {               alert("success"); //登录成功     //        document.getElementById("login").submit(); //登录成功提交表单,跳转到index.jsp这个登录成功页面               window.location=data.url;//登录成功,直接跳转到平台系统页面              }                else if (data.status === "fail"){               alert("fail");//登录失败(用户名或密码错误)               }        },        error:function(){             alert("error"); // 登录失败(超时或服务器其他错误)        }       });       
注:url为单点登录的BI的服务器的地址,其中“localhost:37799”应换为对应的ip地址及端口号。
注:由上述的验证可知,如果设置完毕验证失败:“fail”则表示已传递到BI服务器,但是BI上没验证成功,则要检查BI上是否有这个用户,这个用户的密码是否与传递过来的一致或同步的是明文还是密文检查加密方式;若“error”则是没有传递到服务器上,可能是传递的服务器url不正确或者未传递。
设置button触发doSubmit()
doSubmit()函数写完后,在登录页面上设置点击buttom时触发这个函数即可。其代码如下:
<input type="button" value="登录"   />  
到此ajex的单点登录方式讲述完毕。其完整代码如下:当然具体实施时要根据实际情况进行相应的设置
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="http://localhost:37799/WebReport/ReportServer?op=emb&resource=finereport.js"></script> </script> <script type="text/javascript"> function loginFR() { var username =document.getElementById("username").value; var password =document.getElementById("password").value; var f = document.getElementById("loginForm"); jQuery.ajax({ url:"http://localhost:37799/WebReport/ReportServer?op=fs_load&cmd=sso",//单点登录的报表服务器 dataType:"jsonp",//跨域采用jsonp方式 data:{"fr_username":username,"fr_password":password}, jsonp:"callback", timeout:5000,//超时时间(单位:毫秒) success:function(data) { if (data.status === "success") { alert("success"); //登录成功 // document.getElementById("login").submit(); //登录成功提交表单,跳转到index.jsp这个登录成功页面 window.location=data.url;//登录成功,直接跳转到平台系统页面 } else if (data.status === "fail"){ alert("用户名密码错误!!!"); //登录失败(用户名或密码错误) } }, error:function(){ alert("超时或服务器其他错误!!!");// 登录失败(超时或服务器其他错误) } }); } </script> <body> <form id="loginForm" name="loginForm" method="post" action="index.html"> <table> <tbody> <tr class="prop"> <td class="name"><label> Username</label></td> <td class="value"><input id="username" type="text" name="username" value="" /></td> </tr> <tr class="prop"> <td class="name"><label> Password</label></td> <td class="value"><input id="password" type="password" name="password" value="" /></td> </tr> </tbody> </table> </div></div></div> <div class="actionButtons"> <input id="lalala" type="button" name="lalala" onclick="loginFR();" value ="登录"/> </div> </form> </body> </html>   
注销用户
在单点登录同时登录两个系统后,当注销项目用户时,同时也希望注销报表用户名的session,这时可在点击退出按钮时的同时也可以实现BI退出登录。同单点登录类似,点击退出按钮时触发ajex事件,执行退出命令到BI服务器上,其代码如下:
jQuery.ajax({      url:"http://localhost:37799/WebReport/ReportServer?op=fs_load&cmd=ssout",//单点登录的报表服务器      dataType:"jsonp",//跨域采用jsonp方式      jsonp:"callback",      timeout:5000,//超时时间(单位:毫秒)      success:function(data) {             if (data.status === "logout") {                   //登出成功                }       },      error:function(){            // 登出失败(超时或服务器其他错误)      } }); 
到此ajex单点登录就讲述完了。
1.3 iframe方式单点登录
在OA系统的登录界面的js中将BI的用户权限验证地址以iframe的方式嵌入,然后再在iframe里面触发表单登录事件,进行判断,验证成功即实现登录页面的跳转。这即是iframe单点登录的原理。其触发方式同“ajex方式单点登录”一致,其初始引用代码也相同。如下:
<html>     <head>       <script type="text/javascript" src="ReportServer?op=emb&resource=finereport.js"></script>     <script type="text/javascript">       function doSubmit() {  }
用户认证iframe
在OA系统的登录界面上,doSubmit获取输入的'username'、'password'后,创建iframe,将报表验证用户名密码的认证地址指向此iframe的src。其代码为:
var username = FR.cjkEncode(document.getElementById("username").value); //获取输入的用户名       var password = FR.cjkEncode(document.getElementById("password").value);  //获取输入的参数          var scr = document.createElement("iframe");      //创建iframe         scr.src = " http://localhost:37799/WebReport/ReportServer?op=fs_load&cmd=sso&fr_username=" + username + "&fr_password=" + password;   //将报表验证用户名密码的地址指向此iframe  
认证判断
因为onload事件在不同的浏览器上的实现方式不同,因此在验证登录时要分别进行处理,并将iframe嵌入到head中;验证代码如下:
if (scr.attachEvent){       //判断是否为ie浏览器             scr.attachEvent("onload", function(){                    //如果为ie浏览器则页面加载完成后立即执行                 var f = document.getElementById("login");      /*跳转到指定登录成功页面,index.jsp                    f.submit();  */          });          } else {             scr.onload = function(){              //其他浏览器则重新加载onload事件                  var f = document.getElementById("login");       /*跳转到指定登录成功页面,index.jsp                    f.submit(); */            };       }        document.getElementsByTagName("head")[0].appendChild(scr);   //将iframe标签嵌入到head中         }   
设置触发方式同“ajex方式单点登录”一致,此处不再进行赘述。完整代码如下:
<html>     <head>       <script type="text/javascript" src="ReportServer?op=emb&resource=finereport.js"></script>     <script type="text/javascript">       function doSubmit() {       var username = FR.cjkEncode(document.getElementById("username").value); //获取输入的用户名       var password = FR.cjkEncode(document.getElementById("password").value);  //获取输入的参数              var scr = document.createElement("iframe");      //创建iframe             scr.src = " http://localhost:37799/WebReport/ReportServer?op=fs_load&cmd=sso&fr_username=" + username + "&fr_password=" + password;   //将报表验证用户名密码的地址指向此iframe          if (scr.attachEvent){       //判断是否为ie浏览器                  scr.attachEvent("onload", function(){                    //如果为ie浏览器则页面加载完成后立即执行                       var f = document.getElementById("login");   /*跳转到指定登录成功页面,index.jsp                      f.submit(); */                });               } else {                  scr.onload = function(){              //其他浏览器则重新加载onload事件                       var f = document.getElementById("login");         /*跳转到指定登录成功页面,index.jsp                       f.submit();  */                };            }                document.getElementsByTagName("head")[0].appendChild(scr);   //将iframe标签嵌入到head中        }     </script>       </head>       <body>         <p>请登录</p>         <form id="login" name="login" method="GET"  action="" >           <p>用户名:<input id="username" type="text" name="username" /></p>           <p>密 码:<input id="password" type="password" name="password"/></p>             <input type="button" value="登录"  />         </form>        </body>       </html> 
至此iframe方式单点登录就完成了。
1.4 表单方式单点登录
表单方式是通过form中的action触发url进行验证BI权限验证,方便快捷。action中转向ReportServer,input元素则可看做多个参数自动拼url触发报表认证地址如:ReportServer?op=fs_load&cmd=sso&fr_username=" + username + "&fr_password=" + password,完整代码如下:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK">  </head> <body> <p>     请登录</p> <form action="ReportServer" name="login" method="POST"> <input type="hidden" name="op" value="fs_load"></input> <input type="hidden" name="cmd" value="sso"></input> <p>用户名:<input type="username" name="username"></input></p>    <p>密码:<input type="password" name="password"></input></p>  <input type="submit" value="登录"></input> </form> </body> </html>

若直接输入登录地址,那么登录成功后会自动跳转到指定的页面,若是访问报表系统中的其他地址,比如访问的是一张模板,那么若该用户没有登录过,会先弹出登录界面,登录成功后跳转到访问的那个地址。 

1.5 修改登出地址

在单点登录成功登入后,需要登出平台以切换用户时,有时仍会登出到FineBI登录界面,而不是用户自己的平台界面,此时可以修改登出地址:

在WebReport\WEB-INF\lib中,找到fr-platform-8.0.jar\com\fr\fs\web\frame中的fs.frame.js,搜索signOut,在function方法中找到 window.location.href = res,将其修改为window.location.href = "要登出的地址",保存后重启FineBI服务。

1.6 可能遇到的问题

有时候编辑好单点登录的代码后,单点登录仍无法成功,调试时会发现是由于代码执行过程中用户名和密码的验证请求无法发送出去,此时可以增加几行代码,让页面在当前位置等待几秒钟,让登录平台的请求有足够的时间发送出去,代码如下:

var now = new Date();  var exitTime = now.getTime() + 5000;  while (now.getTime() < exitTime) {  now = new Date();  }
添加位置如下:
function doSubmit(){          var username =FR.cjkEncode(document.getElementById("username").value);              var password =FR.cjkEncode(document.getElementById("password").value);        jQuery.ajax({           url:"http://1.3.8.153:37799/WebReport/ReportServer?op=fs_load&cmd=sso",//单点登录的报表服务器           dataType:"jsonp",//跨域采用jsonp方式           data:{"fr_username":admin,"fr_password":admin},           jsonp:"callback",          timeout:5000,//超时时间(单位:毫秒)           success:function(data) {                  if (data.status === "success") {                  alert("success"); //登录成功       //       document.getElementById("singlelogin").submit(); //登录成功提交表单,跳转到index.jsp这个登录成功页面                window.location=data.url;//登录成功,直接跳转到数据决策系统页面 //   f.submit();                 }                   else if (data.status === "fail"){                  alert("fail");//登录失败(用户名或密码错误)                  }           },           error:function(){                alert("error"); // 登录失败(超时或服务器其他错误)           }           }); var now = new Date();  var exitTime = now.getTime() + 5000;  while (now.getTime() < exitTime) {  now = new Date();  } }

1.7 超链节单点登录

有的时候,用户自己的OA系统本身存在传递用户名和密码的单点登录接口,只需我们设置对应的BI平台的URL地址,将OA系统的用户名和密码的参数嵌入进去作为超链节,进行单点登录即可。如泛微的OA系统即可直接以添加链节节点的方式来完成单点登录。使下如下链节即可:http://localhost:37799/WebReport/ReportServer?op=fs_load&cmd=sso&fr_username=xx&fr_password=xx

示例:以本地测试,用户名:wind 密码:123;如图,返回值 为成功,此时跳转op=fs平台即可登录。

222
按动回车,它会自动跳转过入平台登录界面如下图:

222

1.8 单点登录的session问题

session是用户登录保留的会话机制。用户登录门户系统同时单点登录到BI系统中,其目的就是为了一次性登录,使整个系统形成无缝集成。但是实际上两者依旧是两个系统,使用两套session机制,因此BI系统存在session失效的风险。例:用户单点登录后,用户一直在门户系统上操作,一小时过后,想去查看BI的模板分析。而BI系统以默认的tomcat的session机制,则只有30分钟。一小时过后查看,此时BIsession已丢失,则需要再次登录。单点登录实际是无效的。

解决办法:

1、采用BI嵌入式集成。通过嵌入式集成将两系统并到同一个servlet中,使用同一个session机制,那么用户操作门户系统就不会出去BI系统的session失效。

2、将单点登录登录设置到模板节点上。当打开模板节点时,再执行单点登录。这样设置可能会符合用户的使用场景,但是单点登录的工作量就会增多。q

附件列表


主题: 部署集成
标签: 暂无标签 编辑/添加标签
如果您认为本文档还有待完善,请编辑

文档内容仅供参考,如果你需要获取更多帮助,请咨询帆软技术支持
关于技术问题,您还可以通过帆软论坛获取帮助,论坛上有非常多的大神,有些水平比帆软工程师还要高哦。
若您还有其他非技术类问题,可以联系帆软传说哥(微信ID:frbiaoge)

本文档是否有用?
谢谢! 我们非常感谢您的反馈。
提交反馈: