背景:今天收到一个需求,说cas可以重定向到任意网站,建议对重定向的url进行严格的正则匹配,或者不要使用前端传入的参数作为重定向的依据。

文章目录

  • 一、懒人先看
  • 二、cas的登出流程控制
    • 1、了解Spring webflow
    • 2、登出重定向关键定位
    • 3、再看cas的退出流程
      • 3-1 流程入口
      • 3-2 退出执行
      • 3-3 服务重定向

一、懒人先看

cas登出重定向从设计上讲还是非常优秀的,已经帮你考虑了登出重定向范围的安全控制问题,出现背景中所说问题完全是因为我们的配置不当导致的。
那cas如何开启重定向安全控制呢?
很简单,只需要将cas.logout.followServiceRedirects设为true就好了,系统默认为false。

##
# CAS Logout Behavior
# WEB-INF/cas-servlet.xml
#
# Specify whether CAS should redirect to the specified service parameter on /logout requests
cas.logout.followServiceRedirects=true

那cas是怎么实现重定向安全控制的呢?
接下来就随子涵先生结合cas的流程控制一探究竟吧~

二、cas的登出流程控制

我们知道cas的登录、登出流程是分别通过:login-webflow.xml、logout-webflow.xml定义的。

1、了解Spring webflow

cas登出流程定义使用的技术栈为Spring webflow ,官网地址。如,decision-state流程选择和action-state执行组件:

  • 选择组件
 <decision-state id="serviceCheck"><if test="flowScope.service != null" then="generateServiceTicket" else="viewGenericLoginSuccess" /></decision-state>
  • 执行组件
    <action-state id="redirect"><evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)" result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" /><transition to="postRedirectDecision" /></action-state>

扩展阅读:https://www.cnblogs.com/shuyuq/p/9729791.html

2、登出重定向关键定位

子涵先生顺便和大家扯一点源码阅读中的一些心得~
一般情况下我们有时候无法一下子找到相关业务的源码入口位置,我们可以
1、我们可以先定位到关键代码后使用倒序方式阅读。
2、然后通过正序配置的方式通读源码原理和并深入理解其执行流程。

这里分析源码的时候,我们是按照倒序阅读法来看的。

  • 找到源码重定向到外部url的位置
 <!-- The "redirect" end state allows CAS to properly end the workflow while still redirectingthe user back to the service required.--><end-state id="redirectView" view="externalRedirect:#{requestScope.response.url}" />
  • 找到上一步
<!--检查cas管理的service范围,成功时支持重定向--><action-state id="gatewayServicesManagementCheck"><evaluate expression="gatewayServicesManagementCheck" /><transition on="success" to="redirect" /></action-state>
<!--重定向事件执行,post请求时返回post结果 --><action-state id="redirect"><evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)" result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" /><transition to="postRedirectDecision" /></action-state><decision-state id="postRedirectDecision"><if test="requestScope.response.responseType.name() == 'POST'" then="postView" else="redirectView" /></decision-state>

gatewayServicesManagementCheck是负责服务检测的一个bean,由Spring负责管理。

    <bean id="gatewayServicesManagementCheck" class="org.jasig.cas.web.flow.GatewayServicesManagementCheck"c:servicesManager-ref="servicesManager"/>

查看源码:
org.jasig.cas.web.flow.GatewayServicesManagementCheck

public class GatewayServicesManagementCheck extends AbstractAction {private final Logger logger = LoggerFactory.getLogger(this.getClass());@NotNullprivate final ServicesManager servicesManager;/*** Initialize the component with an instance of the services manager.* @param servicesManager the service registry instance.*/public GatewayServicesManagementCheck(final ServicesManager servicesManager) {this.servicesManager = servicesManager;}@Overrideprotected Event doExecute(final RequestContext context) throws Exception {final Service service = WebUtils.getService(context);final boolean match = this.servicesManager.matchesExistingService(service);if (match) {return success();}final String msg = String.format("ServiceManagement: Unauthorized Service Access. "+ "Service [%s] does not match entries in service registry.", service.getId());logger.warn(msg);throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg);}
}

3、再看cas的退出流程

3-1 流程入口

logout-webflow.xml中定义了基于url的退出方式:

<!-- 通过后端触发的退出 --><action-state id="doLogout"><evaluate expression="logoutAction" /><transition on="finish" to="finishLogout" /><transition on="front" to="frontLogout" /></action-state>

3-2 退出执行

cas将退出动作交给了logoutActionBean,该Bean中的followServiceRedirects参数设置了重定向登出url地址范围:

    <!--  退出功能控制器,前端带你退出走这个action  --><bean id="logoutAction" class="org.jasig.cas.web.flow.LogoutAction"p:servicesManager-ref="servicesManager"p:followServiceRedirects="${cas.logout.followServiceRedirects:false}"/>

logoutAction的源码:

/*** Action to delete the TGT and the appropriate cookies.* It also performs the back-channel SLO on the services accessed by the user during its browsing.* After this back-channel SLO, a front-channel SLO can be started if some services require it.* The final logout page or a redirection url is also computed in this action.** @author Scott Battaglia* @author Jerome Leleu* @since 3.0*/
public final class LogoutAction extends AbstractLogoutAction {/** The services manager. */@NotNullprivate ServicesManager servicesManager;/*** Boolean to determine if we will redirect to any url provided in the* service request parameter.*/private boolean followServiceRedirects;@Overrideprotected Event doInternalExecute(final HttpServletRequest request, final HttpServletResponse response,final RequestContext context) throws Exception {boolean needFrontSlo = false;putLogoutIndex(context, 0);final List<LogoutRequest> logoutRequests = WebUtils.getLogoutRequests(context);if (logoutRequests != null) {for (LogoutRequest logoutRequest : logoutRequests) {// if some logout request must still be attemptedif (logoutRequest.getStatus() == LogoutRequestStatus.NOT_ATTEMPTED) {needFrontSlo = true;break;}}}//==========小哥哥、小姐姐们,看这里~ start===============final String service = request.getParameter("service");if (this.followServiceRedirects && service != null) {final RegisteredService rService = this.servicesManager.findServiceBy(new SimpleWebApplicationServiceImpl(service));if (rService != null && rService.isEnabled()) {context.getFlowScope().put("logoutRedirectUrl", service);}}//==========小哥哥、小姐姐们,看这里~ end===============// there are some front services to logout, perform front SLO//匹配到cas管理的service范围,退出后跳转到对应的service地址。if (needFrontSlo) {return new Event(this, FRONT_EVENT);} else {// otherwise, finish the logout process//否则,退出到cas默认的退出地址return new Event(this, FINISH_EVENT);}}public void setFollowServiceRedirects(final boolean followServiceRedirects) {this.followServiceRedirects = followServiceRedirects;}public void setServicesManager(final ServicesManager servicesManager) {this.servicesManager = servicesManager;}
}

3-3 服务重定向

  • 找到了匹配的服务返回:
    context.getFlowScope().put("logoutRedirectUrl", service);,交给finishLogout
  <decision-state id="finishLogout"><if test="flowScope.logoutRedirectUrl != null" then="redirectView" else="logoutView" /></decision-state>
  • 否则,退出到默认的注销地址

感谢您的赏读,客官,点波赞再走吧~


cas退出流程设置解析之spring webflow的应用相关推荐

  1. cas入门之六:cas 登录流程(下)

    假设cas server服务地址:http://cas-server:8080/cas cas client集成的应用地址:http://cas-client:8070/castest cas cli ...

  2. webflow ajax,java开发之spring webflow实现上传单个文件及多个文件功能实例

    本文实例讲述了java开发之spring webflow实现上传单个文件及多个文件功能.分享给大家供大家参考,具体如下: 上传单个文件 准备 1. 如果你项目中使用了spring security的话 ...

  3. busybox启动流程简单解析:从init到shell login

    https://www.cnblogs.com/arnoldlu/p/10868354.html busybox启动流程简单解析:从init到shell login 关键词:kernel_init() ...

  4. 【运筹学】线性规划 单纯形法 阶段总结 ( 初始基可行解 | 判定最优解 | 迭代 | 得到最优解 | 全流程详细解析 ) ★

    文章目录 一.线性规划示例 二.转化标准形式 三.查找初始基可行解 四.初始基可行解的最优解判定 五.第一次迭代 : 入基与出基变量选择 六.第一次迭代 : 方程组同解变换 七.第一次迭代 : 生成新 ...

  5. spring webflow getting start

    概述 很多时候,我们写的流程都嵌在一大堆代码中,没有办法直观的管理.而spring webflow可以将流程抽出来,放到一个单独的xml文件中,这样流程就不会埋没在代码里了. 今天要做一个很简单的流程 ...

  6. 猥琐思路复现Spring WebFlow远程代码执行

    本文讲的是猥琐思路复现Spring WebFlow远程代码执行,说明:做安全的,思路不猥琐是日不下站的,必须变的猥琐起来,各种思路就会在你脑海中迸发. 1.不温不火的漏洞 这个漏洞在六月份的时候就被提 ...

  7. 爬虫的基本原理:网络爬虫、爬虫基本流程、解析方式、保存数据

    爬虫的基本原理:网络爬虫.爬虫基本流程.解析方式 网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,它们被广泛用于互联网搜索引擎或其他类似网站,可以自动采集 ...

  8. VLC-Android退出流程

    最近在分析一个播放器退出ANR的问题时,详细地跟踪了VLC的退出流程,这里问题的分析先按下不表,我们先结合代码详细了解下播放器的退出流程. 1. java->jni->native的Sto ...

  9. Spring WebFlow 远程代码执行漏洞(CVE-2017-4971)

    一.漏洞描述 Spring WebFlow 在 Model 的数据绑定由于没有明确指定相关 model 的具体属性导致从表单可以提交恶意的表达式从而被执行,导致任意代码执行的漏洞. 二.影响版本 Sp ...

最新文章

  1. qq无限时间撤回消息bug_手机QQ新功能汇总,比微信有意思多了
  2. torchvision0.2.2_速度全面碾压,PCIE4.0 M.2对撞PCIE3.0 M.2
  3. RHEL7 - 从命令行管理文件
  4. TensorRT学习笔记7 - 保存与读取序列化的结果
  5. jzoj4216-[NOIP2015模拟9.12]平方和【Splay】
  6. linux命令(一)查看进程的线程数top,ps
  7. 国外计算机应用基础,计算机应用基础试题(国外英文资料).doc
  8. 测试微信好友是否删除软件,微信测试好友是否删除你的方法
  9. 音频基础之Smaart7声卡测试
  10. 【IPTV】华为IPTV解决方案总体介绍
  11. NetBIOS协议和NBNS协议
  12. 【NLP】第 2 章 访问文本语料库和词汇资源
  13. 自学单片机入门学习建议
  14. element UI 表格序号计算 index
  15. java horizontalbarchart_DOC-03-36 柱状图(Bar Chart)
  16. 软考高项范文——论信息系统项目的成本管理
  17. 0x0F转换成二进制
  18. pion最简单webrtc例子
  19. 关于BD文件的一些操作
  20. 通过WebView实现简单的浏览器

热门文章

  1. HI3559算法移植之OpenCV图像拼接、配准和图像融合技术(三)
  2. 论文查询:如何查询论文被其他哪些文献引用过?
  3. AnchoredSnapper函数使用说明
  4. 将才与帅才的十二个差异
  5. 用python turtle画小黄人源码_Python turtle模块小黄人程序
  6. java小小工具 对象信息管理
  7. 彻底卸载navicat
  8. java字符串取反_Java探索之string字符串的应用代码示例
  9. 035 Android Volley框架进行网络请求
  10. 使用USB 3G上网卡+树莓派搭建接受短信自动转发邮箱的服务