工作中实际遇到的需求,我们有一个旧系统,用了CAS的单点登录,现在有一个外部系统,准备从它那里单点进来,这个外部系统提供了一个token参数来标记这是哪一个用户,我们用他们提供的方式解析出对应的用户,以这个用户从CAS登录进系统。

有关CAS登录的分析网上多如牛毛,这里不准备多作分析了,直接上解决过程。

这里实现是基于我们以前系统的,是CAS 3.5.2
  • 首先在登录流程文件login-webflow.xml里在on-start节点后面插入
<decision-state id="tokenCheck">
<if test="requestParameters.token != null and requestParameters.token != ''" then="tokenValidate" else="ticketGrantingTicketExistsCheck" />
</decision-state>

在这里检查是否有token参数,有的话执行token验证,没有的话走正常流程,ticketGrantingTicketExistsCheck就是原有的正常流程。

  • 定义token验证节点
<action-state id="tokenValidate">
<evaluate expression="tokenLoginAction.doExecute(flowRequestContext)" />
<transition on="error" to="generateLoginTicket" />
<transition on="success" to="sendTicketGrantingTicket" />
</action-state>

失败则走generateLoginTicket分支,会生成一个LT,并重定向到登录页面,这也是通常页面登录失败后的路径

成功则走sendTicketGrantingTicket分支,即页面正常登录成功时走的路径

 
  • 实现token验证流程节点

在cas-servlet.xml里添加添加tokenLoginAction Bean

<bean id="tokenLoginAction" class="org.jasig.cas.web.flow.TokenLoginAction"
p:centralAuthenticationService-ref="centralAuthenticationService" />

实现TokenLoginAction

这里主要解析token,并生成TGT。主要代码如下:

HttpServletRequest request = WebUtils.getHttpServletRequest(context);
String token = request.getParameter("token"); try { //解析Token,略。。。。。。 CasCredentials credentials = new CasCredentials();
credentials.setUsername(userName);
credentials.setPassword("");
credentials.setNoAuth(true); String tgt = centralAuthenticationService.createTicketGrantingTicket(credentials);
WebUtils.putTicketGrantingTicketInRequestScope(context,tgt); } catch (Exception e) {
e.printStackTrace();
return "error";
} return "success";

TokenLoginAction的主要逻辑代码

上面centralAuthenticationService是注入的属性,

CasCredentials则是继承自UsernamePasswordCredentials的一个自定义Credentials,在用户名、密码基础上添加了一个noAuth属性,用来标记是不是需要验证密码。这里由外系统提供的token保证安全性,把noAuth设为true。

而登录验证逻辑在createTicketGrantingTicket这个方法里,验证未通过会抛出异常。

真正验证的地方则是在authenticationManager里,里面有authenticationHandlers定义了验证方法
  • 修改登录验证逻辑

login-webflow.xml顶部把credentials的定义先改了

<var name="credentials" class="com.cas.util.CasCredentials" />

deployerConfigContext.xml找到自定义登录验证所在

<bean id="authenticationManager" class="">
<property name="authenticationHandlers">
<list>
<bean
class="com.cas.util.QueryUserAuthenticationHandler">
......
</bean>
</list>
</property>
</bean>

在这个QueryUserAuthenticationHandler class里,验证密码之前加入

  if (CasCredentials.class.isInstance(credentials)) {
if (((CasCredentials)credentials).isNoAuth())
return true;
}

这样就完成了传入第三方token的CAS登录。

似乎是完成了,但其实还有一些东西,

比如第三方进来的时候是不用他们传Service这个参数的,而这个参数是在CAS登录初始化时处理掉的,后面没有地方自己往request里加这个参数让CAS来处理它,自己写requestscope里写Service对象又很麻烦,看了下代码,得注入很多东西才行。这样就在进入CAS流程前,自己往请求里塞一个Service参数,然后重定向到CAS登录的url。

再比如,这次是别人提供Token用他们的方法解;以后有需求是我们提供一个Token出去,接收进来后用我们的方法自己解。所以其实TokenLoginAction那里解析Token其实是解本方提供出去的Token。解别人的Token呢前置到塞Service参数那个地方,那里解析出来用户名后,再用自己的方法生成一个Token发给CAS。这样就把第三方的Token解析分离出去了,CAS登录的地方不会跟别人的实现绑在一起。

自定义Token的CAS登录的更多相关文章

  1. CAS登录后回传除了ticket参数以外的其他自定义参数

    在一次项目的技术选型中,选择了easyui+cas+shiro+spring的组合,cas实现了单点登录,这使得在一个应用中嵌入另一个应用的页面来展示数据所涉及到的授权方面变得简单. 由于shiro在 ...

  2. jmeter完成CAS登录,并获取token(原创)

    思路: 1.系统完成CAS登录需要验证用户名/密码,以及动态授权参数 2.先通过指定url用正则提取出动态授权参数 3.完成登录需要cookie,需用正则提取出对应的cookie,已完成参数化的自动登 ...

  3. 小D课堂 - 新版本微服务springcloud+Docker教程_6-04 自定义Zuul过滤器实现登录

    笔记 4.自定义Zuul过滤器实现登录鉴权实战     简介:自定义Zuul过滤器实现登录鉴权实战 1.新建一个filter包 2.新建一个类,实现ZuulFilter,重写里面的方法 3.在类顶部加 ...

  4. Struts2透过自定义拦截器实现登录之后跳转到原页面

    Struts2通过自定义拦截器实现登录之后跳转到原页面 这个功能对用户体验来说是非常重要的.实现起来其实很简单. 拦截器的代码如下: package go.derek.advice; import g ...

  5. spring cloud 服务A调用服务B自定义token消失,记录

    后端:spring cloud 前端:vue 场景:前端ajax请求,包装自定义请求头token到后台做验证,首先调用A服务,A服务通过Feign调用B服务发现自定义token没有传到B服务去; 原因 ...

  6. 记录一下gitlab通过CAS登录慢的问题

    测试反应说gitlab通过CAS登录比较慢,第一次登录的时候需要大概30秒才能登录进去 gitlab的日志中有处理每一个请求所用的时间,看了一下日志,每个有记录的请求都是在50毫秒内返回的,所以应该不 ...

  7. JavaWeb -- Struts 自定义拦截器, 登录权限拦截

    1. 自定义拦截器, 登录权限拦截 login.jsp 登录JSP <%@ page language="java" contentType="text/html; ...

  8. CAS登录认证的简单介绍

    参考博客:  https://www.jianshu.com/p/8daeb20abb84 下面是CAS最基本的协议过程: 下面是CAS Web工作流程图: 名词解释 Ticket Grangting ...

  9. 自定义token,保存到客户端的cookie中,

    自定义token #原理自定义token,放入cookie中,不用存数据库 #token定义方式 >>>>> "加密字符串"|登陆用户id|用户登陆时 ...

随机推荐

  1. bind和on的区别

    bind方法与on方法都是事件绑定,但是两者却又有着一个大区别:事件委托 jquery文档中bind和on函数绑定事件的用法: .bind(events [,eventData], handler) ...

  2. Mac/Linux 常用命令

    一 mkdir 创建文件夹 mkdir myApp 在当前目录下创建myApp文件夹. mkdir -p /a/b/c 创建/a/b/c文件夹,如果/a或/a/b不存在,则自动创建. 二 touch ...

  3. sql的日期和时间函数–date_format

    Mysql的日期和时间函数–date_format   DATE_FORMAT(date,format)依照 format 字符串格式化 date 值.下面的修饰符可被用于 format 字符串中:修 ...

  4. python 代码求阶乘

    递归实现 1: #递归实现 def factorial(n): if n == 0: return 1 else: return n * factorial(n - 1)# 递归实现 递归实现 2: ...

  5. rn最新版测试

    1.使用软件版本rn-4.20.4.zipdrago-4.22.03 2.启动drago选择菜单‘对弈’ -> ‘对弈引擎设置’,点按钮‘添加’,选择‘已安装’,输入:姓名‘rn-4.20.4’ ...

  6. 基于SoftRoCE 了解RDMA

    RDMA是基于IB技术的内存直接传送,无需内核参与,硬件网卡搞定.IB需要HPC领域的专用硬件,ROCE则是RDMA协议在普通以太网卡的实现,RoCEv1是在MAC上的二层封装,局域网内可以,要通过路 ...

  7. VirtualBox虚拟机E_INVALIDARG (0x80070057)

    转自:http://www.wzwzl.com/zblog/blog_wz/32.html 打开以前的VirtualBox虚拟机文件时,错误提示:返回 代码:E_INVALIDARG (0x80070 ...

  8. CentOS升级OpenSSL至OpenSSL 1.1.0f版本<其中有遇到libcrypto.so的问题>

    概述: 整体步骤如下: 1.先检查版本 2.进行安装 <安装采用源码安装,然后再做相关的链接指向> 一.检查当前环境 1. 查看当前版本 openssl version 或者使用 yum ...

  9. linux简单安装方法

    一.配置静态IP NAT:模式: 修改网卡eth0 vim /etc/sysconfig/network-scripts/ifcfg-eth0 内容如下: DEVICE=eth0 HWADDR=:0C ...

  10. 微信小程序开发之搞懂flex布局3——Flex Item

    Flex Item flex容器的子元素就是这个容器的flex item. The direct children of a Flex Container (elements with display ...