©Hanson №:2020-10-21
CAS原理和配置:https://blog.csdn.net/fuhanghang/article/details/105356844
【Java】基于CAS单点登录的JavaWeb改造成前后端分离1. 问题场景2. 遇到问题1. Ajax无法进行重定向2. Ajax默认不带Cookie信息3. 流程图解
1. 问题场景
需要将传统的SpringMVC项目(页面使用Jsp)改造成前后端分离的项目。
方案:
前端服务Server-A
:原始项目的Controller层只保留页面跳转的接口,去掉数据返回的接口。
后端服务Server-B
:原始项目的Controller层只保留数据返回的接口,去掉页面跳转的接口。
Server-A
和 Server-B
分别部署在不同的tomcat上。
2. 遇到问题
1. Ajax无法进行重定向
通过
Server-A
登录CAS
后,ajax请求Server-B
时会重定向(http302)到登录页面,但ajax无法完成重定向。
方案: 使用隐藏iframe的方式登录Server-B
initIframe: function(){ $("body").append(");}
在登录Server-A
之后,会自动将CAS
的登录信息写入Cookie,仅需在登录Server-A
之后调用一次上面的function,就会登录Server-B
并自动将Server-B
的登录信息写入Cookie。
2. Ajax默认不带Cookie信息
Server-A
到Server-B
需要跨域
Server-A
请求Server-B
时需要携带Server-B
的Cookie信息,以便在Server-B
中获取用户信息。
方案: Server-B
支持跨域,Server-A
的ajax携带Cookie。
Server-B
:
在
spring-mvc.xml
设置跨域<mvc:cors> <mvc:mapping path="/**" allowed-origins="Server-A的host:port" allowed-methods="GET,POST,OPTIONS,DELETE,PUT" allowed-headers="*" allow-credentials="true"
设置过滤器(为了配合带Cookie的请求)
import javax.servlet.*;import java.io.IOException;@WebFilter(filterName="corsResponseFilter", urlPatterns={"/*"})public class CorsResponseFiler implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){ HttpServletResponse response = (HttpServletResponse)servletResponse; resposne.setHeader("Access-Control-Allow-Origin", "Server-A的ip:host"); resposne.setHeader("Access-Control-Allow-Credentials", "true"); filterChain.doFilter(servletRequest, servletResponse); }}
Server-A
:
所有ajax请求带上
xhrFields
和crossDomain
参数思考:监听所有ajax,统一加上
xhrFields
和crossDomain
参数$.ajax( url: `Server-B`/api/xxx, type:'POST', dataType:'json', xhrFields:{ withCredentials: true }, crossDomain:true, success: function(res){ console.log(res); })
3. 流程图解
step1: 通过浏览器访问Server-A
step2: Server-A
重定向到CAS
的登录页,输入用户名和密码
step3: CAS
将登录CAS
需要的Cookie和登录Server-A
的Cookie写入到浏览器
step4: 成功登录Server-A
之后立刻通过隐藏iframe的形式访问Server-B
step5: 由于浏览器Cookie拥有CAS
的Cookie信息,所以Server-B
到CAS
不需要输入用户名和密码
step6: CAS
将Server-B
的登录信息写入Cookie
以上步骤完成后。当浏览器访问Server-A
的页面,该页面中通过ajax调用Server-B
的接口时,由于设置了允许跨域且携带Server-B
的Cookie信息,所以能成功获取到数据。