一种Cas登录验证增加动态参数的实践方案

前言

本文主要解决的技术问题:

  1. CAS登录页面怎样增加除用户名,密码以外的参数,例如要增加用户身份?
  2. CAS server认证成功后,怎么返回对应身份的用户信息?

怎么解决上述问题呢?

思路:

  1. 弄明白Cas的基本概念 
  2. 弄明白Cas是怎么使用的
  3. 弄明白Cas-server代码实现流程
  4. 弄明白问题对应代码切入点

接下来是具体实践过程:

一、CAS是什么

直接百度:CAS(中央认证服务)

其中对协议过程图的分析,可以清楚CAS 通信原理。

二、CAS是怎么使用

网上找到实战springboot+CAS单点登录系统课程,介绍了cas-server 与 cas-client的搭建,掌握cas基本使用。不足之处,课程对cas-server环境搭建直接使用的war包tomcat部署,对于cas-server后台源码实现流程没有做详细分析。

课程地址:

cas 实践

war包下载地址:

https://repo1.maven.org/maven2/org/apereo/cas/cas-server-webapp-tomcat/

三、Cas实现流程

了解Cas使用后,发现cas-server通过不同的参数配置策略,实现单点登录,对于各个配置文件的介绍:Cas Server配置文件

博文说“login-webflow.xml:登录使用到的Spring Web Flow配置文件”,引出了Spring Web Flow这种技术,Spring Web Flow在cas 是怎么使用的,可阅读下面博文:

Spring Web Flow —— 基础 - 011_zou8944的博客-CSDN博客_web-flow

CAS学习笔记(二)—— cas server端的login-webflow详细流程_qq_30220585的博客-CSDN博客

弄清楚login-webflow 就会了解cas的登录流程。第二篇博文中提到了casLoginView.jsp这个文件,通过阅读cas登陆页面修改服务器端 发现casLoginView其实就是登录页,是解决问题的切入点之一,casLoginView.jsp文件中大量使用了<form:xxx> 标签,说明页面的实现采用了springmvc form技术,实现原理见博文 SpringMVC - Form标签

Cas Server配置文件博文中:“deployerConfigContext.xml:该文件是专为Cas Server部署人员抽取出来的一个文件,其中的内容通常都是Cas Server部署人员需要进行更改的内容”。在cas 实践课程中也提及到,通过配置deployerConfigContext.xml 文件可以实现数据源认证,那么认证过程中,是不是可以添加更多的查询参数返回所需结果,这里也是问题切入点。deployerConfigContext  使用详解

CAS多条件查询与更多数据返回

至此就会对cas实现流程有一个相对深刻的认识,接下来就是问题的解决。

四、问题解决

在问题解决之前,先看一下这篇博文:

cas服务器登录页面添加验证码

文章提供了UsernamePasswordCredential扩展字段,校验字段的方法。

现在开始问题的解决:

登录页面怎样增加除用户名,密码以外的参数?

  • 修改casLoginView.jsp 增加 swrysfSelect下拉框,及 swrysf 隐藏域
<div class="kema_shuru1" style=" position: relative;">
	<div class="kema_shurmingc"></div>
		<spring:message code="screen.welcome.label.netid.accesskey"
			var="userNameAccessKey" />
		<span style=" position: absolute; top:5px; left:10px;"><img src="${basepath}static/images/login/user_icon.png" /></span>	
		<form:input id="username" tabindex="1"
			accesskey="${userNameAccessKey}" type="text" cssClass=""
			class="kema_inpyonghum" value="" placeholder="请输入您的用户名"
			path="username" autocomplete="false" htmlEscape="true" />
</div>

<div class="clearfix"></div>
<div class="kema_shuru1" style=" position: relative; margin-top:0px; margin-bottom: 0px;">
	<div class="kema_shurmingc" style="height: 40px;"></div>
	<span style=" position: absolute; top:5px; left:10px;"><img src="${basepath}static/images/login/password_icon.png" /></span>
	<form:password id="password" type="password" cssClass=""
		class="kema_inpyonghum" value="" placeholder="请输入您的密码"
		tabindex="2" path="password" accesskey="${passwordAccessKey}"
		htmlEscape="true" autocomplete="off" />
</div>

<div class="clearfix"></div>
<div class="kema_shuru1" style=" position: relative;margin-top:20px;margin-bottom:-20px;">
	<div class="kema_shurmingc"></div>
	<span style=" position: absolute; top:5px; left:10px;"><img src="${basepath}static/images/login/user_icon.png" /></span>
	<select id="swrysfSelect" class="kema_inpyonghum">
	
	</select>
	<form:input path="swrysf" id="swrysf" name="swrysf" type="hidden" ></form:input>
</div>

其中:swrysfSelect 是一个下拉框的数据是username失去焦点后,异步数据查询动态创建的。

swrysf 在swrysfSelect值改变时,会绑定对应选中值。

  • UsernamePasswordCredential扩展,增加字段

参考cas服务器登录页面添加验证码,新建类UsernamePasswordAndSwrySfCredentials,添加一个swrysf字段:

/**
 * 用户密码身份
 */
public class UsernamePasswordAndSwrySfCredentials extends UsernamePasswordCredentials{
    private static final long serialVersionUID = 1L;

    @NotNull
    private String swrysf;

    public final String getSwrysf() {
        return swrysf;
    }

    public final void setSwrysf(String swrysf) {
        this.swrysf = swrysf;
    }

}
  • login-webflow credentials变量修改为UsernamePasswordAndSwrySfCredentials
    <!--<var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />-->
	<var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordAndSwrySfCredentials" />
    <on-start>
        <evaluate expression="initialFlowSetupAction" />
    </on-start>


...... 省略部分代码


	<view-state id="viewLoginForm" view="casLoginView" model="credentials">
        <binder>
            <binding property="username" />
            <binding property="password" />
			<binding property="swrysf" />
        </binder>
        <on-entry>
            <set name="viewScope.commandName" value="'credentials'" />
        </on-entry>
		<transition on="submit" bind="true" validate="true" to="submit">
            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
        </transition>
	</view-state>

登录提交时 username password swrysf  绑定到 UsernamePasswordAndSwrySfCredentials对应字段中。

接下来是处理返回对应身份的用户信息信息:

deployerConfigContext.xml 配置

<bean  class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao" id="attributeRepository">
    <constructor-arg index="0" ref="dataSource"/>
    <constructor-arg index="1" value="select * from table where {0} "/>
    <property name="queryAttributeMapping">
        <map>
            <entry key="username" value="dlzh_dm"/>
            <entry key="swrysf" value="swrysf_dm"/>
        </map>
    </property>
    <property name="resultAttributeMapping">
        <map>
            <entry key="返回字段1" value="返回字段1"/>
            <entry key="返回字段2" value="返回字段2"/>
            <entry key="返回字段3" value="返回字段3"/>
            <entry key="返回字段4" value="返回字段4"/> 
        </map>
    </property>
</bean>

修改AbstractPersonDirectoryCredentialsToPrincipalResolver.java

        //修改方式getPerson 方法 由调用 principalId(username) 的方式 改为调用 Map 的方式,Map 包括 username及swrysf 参数
        //final IPersonAttributes personAttributes = this.attributeRepository.getPerson(principalId);

        Map<String,Object> params = new HashMap<String, Object>();
        UsernamePasswordAndSwrySfCredentials credentialsWithSwrySf = (UsernamePasswordAndSwrySfCredentials)credentials;
        params.put(USERNAME,credentialsWithSwrySf.getUsername());
        params.put(SWRYSF,credentialsWithSwrySf.getSwrysf());

        Set<IPersonAttributes> people = this.attributeRepository.getPeople(params);
        Iterator<IPersonAttributes> iterator = people.iterator();
        final IPersonAttributes personAttributes = iterator.next();
        final Map<String, List<Object>> attributes;

这样 select * from table where {0} sql  会替换成 select * from table where dlzh_dm = ? and swrysf_dm = ?  同时绑定params 参数值,就可以返回具体身份下的人员信息。

问题解决

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值