如何在 CAS 单点登录环境下发送 Ajax 请求?

黄勇 发布于 2014/02/09 17:17
阅读 10K+
收藏 4

武汉源创会回归,4月20聊聊大模型”

我已成功大家 CAS 单点登录服务器(简称 CAS),地址为:https://cas

有两个应用,已经它们集成在单点登录环境中,它们是:

  • REST Server,地址为:http://rest-server
  • REST Client,地址为:http://rest-client

当进入 REST Client 时,发送请求:http://rest-client/product.html

由于没有认证,所以该请求将会被重定向到 CAS 上,此时请求为:https://cas/login?service=http://rest-client/product.html

重定向到 CAS 的登录页面,输入用户名与密码,CAS 判断认证成功后,将请求重定向到:http://rest-client/product.html

此时,在 product.html 页面中,通过一个 jQuery Ajax 请求去获取 REST Server 上的数据,代码如下:

$.ajax({
    url: 'http://rest-server/ws/rest/ProductService/products', // 注意这个 URL
    success: function(data) {
        // data 是一个 JSON 数据,可渲染到 DOM 上
    }
});

此时,发现 Ajax 请求出现问题,Status Code 为 302 Found。

如果直接在浏览器地址栏上发送这个 URL,再次刷新页面,就可以获取 JSON 数据。

目前我的解决方案不太优雅,使用了一个 iframe 来发送这个 URL,代码如下:

$.ajaxSetup({
    error: function(jqXHR, textStatus, errorThrown) {
        if (textStatus == 'error' && errorThrown == '') {
            if (jqXHR.status == 0 || jqXHR.status == 12017) {
                var $iframe = $('<iframe/>', {
                    src: url,
                    style: 'display: none;'
                });
                $iframe.appendTo('body');
                $iframe.load(function() {
                    location.reload();
                });
            }
        }
    }
});

当发现 Ajax 错误时,需要定位到这种错误类型,然后动态生成一个隐藏的 iframe,在这个 iframe 里发送这个 URL,并监听了 iframe 加载完毕的事件,当加载完毕后,自动刷新页面,这样一来 Ajax 请求才能正确获取 REST Server 端的数据。

注意:该示例中用到了 Ajax 跨域,我使用的是 CORS 解决方案,即在 REST Server 端指定的 origin 为 REST Client 的地址。

我的问题是,如何解决在 CAS 单点登录环境下发送 Ajax 请求?

加载中
0
Avro
Avro
这个是没办法的,ajax的安全性阻碍了这条策略,使用jsonp吧
黄勇
黄勇
非常感谢你的解决方案! 之前我使用的是 CORS,可以解决 Ajax 跨域问题,但无法解决 Ajax 重定向问题。 现在我改为了 JSONP,这样 Ajax 跨域与重定向问题都解决了。 看来 Ajax 跨域问题,首选还是 JSONP!
0
Sam_yi
Sam_yi

建议你先用HTTP watch 看下Ajax 调用是 具体返回的是什么错误 

我在CAS环境中没有遇到过Ajax 调用问题 

黄勇
黄勇
我把问题稍微补充了一下,请见楼下的回答。
0
黄勇
黄勇
该评论暂时无法显示,详情咨询 QQ 群:点此入群
0
pantrick
pantrick
b不明白为啥你的ajax需要重新登陆,ajax所在域没有成功登陆cas吗,类似的场景我也做过,只要所在机器成功登陆了cas,ajax怎么发送也不需要重新定向,ajax发送请求和普通http有差别吗!  
0
nathanwu
nathanwu
http://rest-server/ws/rest/ProductService/products 估计是这个url被cache住了,试一试这个url http://rest-server/ws/rest/ProductService/products?time=xxxxxxxxxxx
0
我是李达康
我是李达康
该评论暂时无法显示,详情咨询 QQ 群:点此入群
我是李达康
我是李达康
@黄勇 这不是事儿,我也是给他点个赞嘛,哈哈
黄勇
黄勇
同样感谢你的答复!但 @RevenAn 比你稍微早半个小时回复了,所以最佳答案就给他了,不好意思哦!
0
黄勇
黄勇

这里有一篇文章,欢迎评论!http://my.oschina.net/huangyong/blog/198519

0
joock
joock

对于同域名,不同子域名的应用,即大多数企业内部应用而言。

默认的情况下,存储ticket的cookie在某个子域,只需要将此cookie的域改为*.域名,是不是就可以了? :)

cas-client拿到ticket直接去鉴权,不必2次302跳转~

0
任X立
该评论暂时无法显示,详情咨询 QQ 群:点此入群
0
janche
janche

我有一个方案,可以绕过cors的ajax重定向的问题。
我使用的是OAuth2 + Spring Security,虽然框架不一样但遇到的问题基本一致。
1. 客户端前后端不分离,将不会出现这种跨域问题,或者前后端分离,但是你将客户端的前端给放在客户端的服务端中一起部署,这样也不会出现这种ajax重定向问题。
2. 如若确实客户端前后端不能部署在一起,可让客户端前端请求ajax数据之前,先单独打开一个小的窗口去请求ajax数据,这一步只是为了认证,因为会涉及到重定向服务端,所以需要打开一个新的小窗口,或者打开新的标签页都行。(我也试过iframe,打开后iframe的页面无法显示,或许和我的服务端前后端分离也有关系)
 

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部