当前位置: 移动技术网 > IT编程>开发语言>Java > 自定义Token的CAS登录

自定义Token的CAS登录

2019年01月26日  | 移动技术网IT编程  | 我要评论
工作中实际遇到的需求,我们有一个旧系统,用了CAS的单点登录,现在有一个外部系统,准备从它那里单点进来,这个外部系统提供了一个token参数来标记这是哪一个用户,我们用他们提供的方式解析出对应的用户,以这个用户从CAS登录进系统。 有关CAS登录的分析网上多如牛毛,这里不准备多作分析了,直接上解决过 ...

工作中实际遇到的需求,我们有一个旧系统,用了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登录的地方不会跟别人的实现绑在一起。

 

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网