项目场景:
项目场景:统一门户项目用到了若依前后端分离版本和CAS5.3.14搭建的,相关集成步骤我在之前的文章中已经提到感兴趣的可以移步到此: 若依前后端分离版本集成CAS Server5.3_qq_27230853的博客-CSDN博客_若依集成cas
若依前后端分离集成CAS后的部署_qq_27230853的博客-CSDN博客_若依集成cas
问题描述
在后期客户的使用中,也是由于场景不同遇到了很多问题,下面我们就一一罗列一下然后说说解决方案。客户的电脑都是老机子,上面装的还是360极速浏览器,由于以前客户有一个OA的门户,所以他们也想从以前的门户直接进入我们的门户,就此需求引发了以下3个问题:
1,他们以前都是在兼容模式下运行,而我们现在开发的已经不支持兼容模式了,所以从他们哪块要兼容模式进入,跳转到我们门户要变成极速(坑吧)。
2,在第一个问题花了差不多有半个月时间查资料做验证终于做完之后又发现一个问题,就是浏览器双核切换的时候cas的TGC不识别导致从OA登录门户成功了但是我们门户进入其它系统单点不成功了。
3,CAS的自定义认证,我们的CAS是集成通过JDBC直接连接数据库认证的,可是人家已经做了好多系统切用户没有完全统一想借着我们门户这次的实施达成统一(登录口令和密码统一),其中登录口令包括手机号、员工编号、内部账号。
分析与解决:
针对以上3个问题我们一一分析与解决:
1,第一个问题说白了就是双核浏览器的切换,小编第一次遇到天真的以为不可能解决,因为浏览器安全的问题你前端是不可能控制浏览器模式的变换(浏览器不会有类似的API),若真是怎样那以后谁都能通过Web来操控你电脑了,但是通过查阅大量资料以及对项目的分析还真有可能实现。实现的前提是你的项目必须是前后端分离,因为在登录成功跳转的必须是前端页面才能正确切换,正好我们采用了若依的前后端分离的架构正好可以,解决方式在cas登录成功跳转的首页添加对应的meat标签,网上文章很多我就找了其中一篇:html设置360兼容/极速模式_a13520165516的博客-CSDN博客。解决完切换的问题就要解决cas模拟登录的问题,这个我们通过看CAS登录的源码发现是通过正常的form请求来登录的,原本想通过RestAPI的方式让客户登录,可是发现API接口不好用,而且目前CAS5.3相关的源码已经没了也没办法继续研究,因此我们尝试通过Ajax调用来模拟登录,在模拟过程中发现CAS有页面流的概念每次页面刷新都有一个页面流ID,因此我们通过2次Ajax的方式先去获取页面流ID再登录,最终成功登录cas,登录代码如下:
$.ajax({
url:"http://sso.demo.com/cas/login",
async:false,
crossDomain: true,
xhrFields:{withCredentials :true},
type:"POST",
dataType: "html",
success:function(result){
var re=/\b(value=")\S*=/;
var matchResult=result.match(re);
if(matchResult!=null&&matchResult.length>0){
var execution=matchResult[0].replace("value=\"","");
$("[name='execution']").val(execution);
$.ajax({
url:"http://sso.demo.com/cas/login",
async:false,
crossDomain: true,
xhrFields:{withCredentials :true},
type:"POST",
dataType: "html",
data: $("[name='mylogin']").serialize(),
success:function(result){
//前端首页地址
window.open("http://app.url.com","_blank");
},
error:function(XMLHttpRequest, textStatus, errorThrown){
// 状态码
console.log(XMLHttpRequest);
// 错误信息
console.log(textStatus);
// 错误信息
console.log(errorThrown);
}
});
}else{
//前端首页地址
window.open("http://app.url.com","_blank");
};
}
});
其中form表单代码如下:
<form id="mylogin" name="mylogin" method="post" action="http://cas.demo.com/cas/login">
<input type="hidden" name="execution" value="" />
<input type="hidden" name="username" value='admin' />
<input type="hidden" name="password" value='admin123' />
<input type="hidden" name="_eventId" value='submit' />
<input type="hidden" name="geolocation">
</form>
其中获取execution我还找到一篇文章通过$.getJSON,相关链接:模拟CAS单点登录(跨域提交、js正则匹配)_pitt1997的博客-CSDN博客但是没有尝试通过(猜测是因为浏览器兼容模式的原因)感兴趣的可以去尝试一下,这样能让代码更简洁。
2,在CAS模拟登录成功后发现其它系统还是会跳转到cas的登录页面,于是查看了一下Cookie,发现登录成功后Cookie会多一个TGC,查询了一些资料发现TGC和Ticket是不同的,又翻看一些资料发现在双核浏览器下TGC的认证方式也不一样这就导致你在兼容模式下登录成功后极速模式下是不认的,为了解决这个问题有2个方法,一是重写TGC的认证,毕竟CAS的安全是通过TGC来控制的,二是通过修改cas配置文件的方式这种方式在内网的话是没有问题的,若是项目在公网上就不建议使用,配置属性:cas.tgc.crypto.enabled=false 位置在cas部署包的application.properties文件中。
3,由于我们门户的密码加密方式和其它系统的不一样导致客户觉得要记好多密码记不住,因此需要我们进行用户口令和密码的统一,为此我们达成一个协议以后所有的用户都读取同一个库,而门户这边需要那个项目的密码加解密的方式,通过CAS的自定义认证最终实现了客户通过不同账号相同密码的方式来进行登录,CAS通过JDBC部署的方式是需要初始化一些表的,因此我们对此进行了改造,可以让service注册读取门户的库,让用户认证读取我们协定好的库这样门户这边只是需要定期同步那个库的用户即可,密码哪些懂不用维护。我自己写的代码就不粘贴了大家可以参考下这篇文章:cas5.3.2单点登录-自定义登录验证(四)_这个名字想了很久的博客-CSDN博客_cas自定义登录验证
|