• 基于CAS的SSO单点登录-实现ajax跨域访问的自动登录(也相当于超时重连)


    先补课,以下网址可以把CAS环境搭起来。

    【JA-SIG CAS服务环境搭建】http://linliangyi2007.iteye.com/blog/165307

    【JA-SIG CAS业务架构介绍】http://linliangyi2007.iteye.com/blog/165310

    【JA-SIG CAS技术框架】http://linliangyi2007.iteye.com/blog/165313

    【抓包分析】http://blog.csdn.net/clh604/article/details/20365967

    【问题背景】两个系统的整合就不说了,简单来说就是网页放在NginX上,但是ajax调用tomcat的API获取数据,其中tomcat段用CAS做身份认证。具体使用的是org.jasig.cas.client,配置会略有不同就不展开了。

    【问题描述】ajax调用不允许跨域访问,如果在该容器中未CAS登陆(没有ticket)则会遇到以下错误。

    XMLHttpRequest cannot load [CAS服务器地址] No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin [应用地址] is therefore not allowed access.

    【非ajax请求具体的跳转请求】就是标准的跳转,不上图了:

    请求1:http访问tomcat。结果:302重定向指向CAS服务器

    请求2:访问CAS服务器,带上CASTGC。结果:302重定向指向tomcat并带上ticket

    请求3:访问tomcat,带上ticket。结果:200返回资源

    【ajax请求具体的跳转请求】:

    请求1:ajax访问tomcat。结果:302重定向指向CAS服务器

    请求2:访问CAS服务器,带上CASTGC。结果:200返回无内容,浏览器提示错误(chrome)

    跨域访问规则Access-Control-Allow-Origin是在CAS服务器配置的,项目无法更改。

    【参考的解决方法】

    a.在session超时的情况下发ajax请求。返回200正常,并在json中指定状态码302和login.action地址

    b.访问login.action。302重定向指向CAS服务器

    c.访问CAS服务器登录授权。302重定向回login.action

    d.访问login.action带有ticket。302重定向next_page(即一开始ajax请求的页)

    e.访问next_page刷新整个页

    【具体解决过程】

    1.修改CAS授权过滤器,session无效的ajax请求先返回200正常,并在json中指定业务错误码session_lost

    继承修改AuthenticationFilter的doFilter方法:

    a.如果session中有assertion,通过,进入下一层(tomcat端向CAS服务器验证ticket)

    b.(无assertion)如果有ticket,通过,进入下一层filter(tomcat端向CAS服务器验证ticket)

    c.(无assertion无ticket)普通http请求,重定向到CAS服务器

    d.(无assertion无ticket)ajax请求,返回200并在json中指定session_lost

    e.改配置web.xml,指向新的AuthenticationFilter类,并且serverName要与NginX的域名匹配

    2.在js的callback中处理session_lost,将网址定位到/login.action

    window.location.href=/app/login.action

    3.在java的/autoLogin中重新登录并根据参数next_page重定向,完成登录和刷新

    (因为是普通http请求,会先跳转到CAS登录,回来建立session信息,然后再跳转到用户本来的页面)

    【其中一些细节问题】

    a.通过检查请求头的"X-Requested-With"为"XMLHttpRequest"鉴别是ajax调用

    b./login.action中要判断nextpage避免指向自己,若"/login.action?nextpage=/login.action"会导致死循环,爆栈很欢乐~

    c.登录后cookies对JSESSIONID写入不对也会导致session找不到而死循环,一番排查后发现Tomcat写入的cookies匹配的path是应用路径,而网页上匹配的是根路径,所以需要手动写cookies把JSESSIONID匹配path为"/"。

    d.web.xml中serverName要与网页域名匹配(因为这里经过了DNS和反向代理),否则会报登录的service与当前访问的service(即域名)不匹配的错误。

    e.几种跳转方式的区分

    request.getRequestDispatcher(str).forward(request, response);
    ---服务器内部跳转,路径从应用开始算,即"/"等效于 "http://域名/应用/"
    
    response.sendRedirect(str);
    ---浏览器端302重定向,参数为完整地址。
    
    @Controller实例的方法中的return str;
    ---服务器内部加载页面,路径从应用开始算。
    
    @Controller实例的方法中的return "redirect:/";
    ---浏览器端302重定向,但是路径从应用开始算。
    
    浏览器端js中window.location.href
    ---浏览器本窗口打开页面,路径从域名后开始计算,即"/"等效于 "http://域名/"

    f.warnning:第一个是CSRF风险即cookies被盗用,电脑入域或网络隔离可规避;第二个是serverName配置是写死在web.xml上,改域名就要重新部署应用,可改为配置。

    完事,可以ajax随便愉快玩耍了~

  • 相关阅读:
    使用openURL实现程序间带参数跳转详解
    [翻译] DFCircleActivityIndicator DF圆形活动状态指示器
    ABC定制视图导航控制器
    [翻译] UIView-draggable 可拖拽的UIView
    [翻译] SFRoundProgressCounterView 带有进度显示的倒计时视图
    [翻译] ColourClock 将时间值转换成背景色
    Solr部署如何启动
    搜索引擎基本工作原理
    面试题 IQ
    解释一下,在你往浏览器中输入一个URL后都发生了什么,要尽可能详细
  • 原文地址:https://www.cnblogs.com/syjkfind/p/4370092.html
Copyright © 2020-2023  润新知