CAS单点登录-自定义认证之JDBC+MD5(四)

本文详细介绍了在CAS认证系统中使用JDBC进行认证的方法,包括密码加密策略的实施,如MD5、SHA和HMAC算法的应用,以及如何通过加盐处理提高密码安全性。

本章节的内容为JDBC认证,查找数据库进行验证,其中包括:

  • 密码加密策略(无密码,简单加密,加盐处理)
  • 认证策略(jdbc)

业务需求

在不同公司,可能有很多业务需求或者架构不一样导致我们实现验证的方式不一样,那么cas为我们提供了很多认证的模式(当然也可以自定义),其中常用的有:

  • JDBC认证
  • LDAP认证
  • Basic认证
  • Shiro认证
  • Pac4j认证
  • MongoDB认证
  • Rest认证
  • IP黑白名单
    还有可能交给第三方认证,例如:微信、QQ、新浪等等

当然也有一些公司或者企业也非常的变态,如:

  1. 认证中心不能直接访问账号库,cas也提供功能,可以考虑用REST认证模块来处理这个事情
  2. 老系统账号唯一性不确定,例如 组织+账号 才是唯一值,这时候只能自定义认证器(后面章节会有教程)
  • 业务系统要求返回用户密码(多属性返回/ClearPass)

加密方案

cas支持jdbc校验方案:

  • 根据sql给予用户名进行查询,根据密码字段进行鉴定(select * from table_users where username=?)可判断有效等
  • 通过盐等手段进行编码加密再进行匹配(推荐)
  • 根据sql给予用户名以及密码进行查询(select count(x) from tables_users where username = ? and password=?),不可判断有效期,若数量大于0则成功
  • 根据用户名密码连接数据库,原理是通过jdbc,若连接成功则成功

JDBC验证

采用mysql数据库存储用户数据。

修改pom.xml
sso-server/pom.xml:

<!--新增支持jdbc验证-->
<dependency>
    <groupId>org.apereo.cas</groupId>
    <artifactId>cas-server-support-jdbc</artifactId>
    <version>${cas.version}</version>
</dependency>


<!-- mysql驱动 根据不同的数据库使用不同驱动-->
<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
    <version>5.1.16</version>
</dependency>

<!--
若不想找驱动可以直接写下面的依赖即可,其中包括
HSQLDB、Oracle、MYSQL、PostgreSQL、MariaDB、Microsoft SQL Server
-->
<!--
<dependency>
   <groupId>org.apereo.cas</groupId>
   <artifactId>cas-server-support-jdbc-drivers</artifactId>
   <version>${cas.version}</version>
</dependency>
-->

表结构

sys_user:


11464886-f2fc3205269d82bb.png
create table sys_user
(
   id                   int not null auto_increment,
   username             varchar(40),
   password             varchar(200),
   expired              int comment '1为过期 需要修改密码',
   disable             int comment '1为不可用,禁用',
   email                varchar(200),
   primary key (id)
);

CAS Authentication Credentials

根据sql给予用户名进行查询,根据密码字段进行鉴定(select * from sys_user where username=?

程序新增配置

##
# CAS Authentication Credentials
#
#cas.authn.accept.users=casuser::Mellon

#Query Database Authentication 数据库查询校验用户名开始
#查询账号密码sql,必须包含密码字段
cas.authn.jdbc.query[0].sql=select * from sys_user where username=?
#指定上面的sql查询字段名(必须)
cas.authn.jdbc.query[0].fieldPassword=password
#指定过期字段,1为过期,若过期不可用
cas.authn.jdbc.query[0].fieldExpired=expired
#为不可用字段段,1为不可用,需要修改密码
cas.authn.jdbc.query[0].fieldDisabled=disabled
#数据库方言hibernate的知识
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
#数据库驱动
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
#数据库连接
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost/sso?characterEncoding=utf8
#数据库用户名
cas.authn.jdbc.query[0].user=root
#数据库密码
cas.authn.jdbc.query[0].password=123456
#Query Database Authentication 数据库查询校验用户名结束

以上配置,如驱动,查询数据库等等需要根据不同的场景进行调整

常用单向加密算法:MD5、SHA、HMAC。

一般我们常用的加密算法就这几种。在JDBC认证中我们也可以选择配置加密算法,加密算法一般为上面的三种,MD5、SHA、HMAC,加密类型为NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2这几种,我们在配置文件中选择加密类型,指定加密算法。

11464886-cebbaef30253ba96.png

普通MD5加密配置

前面配置不变指定JDBC配置,后面的配置为密码加密策略,配置如下:

#默认加密策略,通过encodingAlgorithm来指定算法,默认NONE不加密
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5

执行流程(如输入账号密码为 admin/123):


11464886-ad6f82995c2da8a2.png

登陆成功:

然后我们启动应用。当我们运行起CAS,输入原来的用户名和密码admin/123456,并不能登录,因为我们更改密码验证为MD5加密模式了。将123456使用md5加密后,填入数据库,再次登录,可以发现登录成功。由此验证我们加密成功!

11464886-aefaa3628b3a6ad0.png

对密码进行盐值处理(推荐)官方实例

上一步只是对密码进行了简单的加密,两个帐号有可能相同的值,就能判断出密码是一致的,但通过此方案,大大增加了难度,所以安全系数也高了许多,推荐使用策略。
在上面的基础上,再添加如下代码,可以共存,:

#加密迭代次数
cas.authn.jdbc.encode[0].numberOfIterations=2
#该列名的值可替代上面的值,但对密码加密时必须取该值进行处理
cas.authn.jdbc.encode[0].numberOfIterationsFieldName=
#盐值固定列
cas.authn.jdbc.encode[0].saltFieldName=username
#静态盐值
cas.authn.jdbc.encode[0].staticSalt=.
cas.authn.jdbc.encode[0].sql=SELECT * FROM sys_user WHERE username =?
#对处理盐值后的算法
cas.authn.jdbc.encode[0].algorithmName=MD5
cas.authn.jdbc.encode[0].passwordFieldName=password
cas.authn.jdbc.encode[0].expiredFieldName=expired
cas.authn.jdbc.encode[0].disabledFieldName=disabled
#数据库连接
cas.authn.jdbc.encode[0].url=jdbc:mysql://127.0.0.1:3306/sso?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.encode[0].dialect=org.hibernate.dialect.MySQL5Dialect
cas.authn.jdbc.encode[0].driverClass=com.mysql.jdbc.Driver
cas.authn.jdbc.encode[0].user=root
cas.authn.jdbc.encode[0].password=123456

加密生成类:

//固定盐生成类
public class PasswordSaltTest {
    private String staticSalt = ".";
    private String algorithmName = "MD5";
    private String encodedPassword = "123456";
    private String dynaSalt = "test";

    @Test
    public void test() throws Exception {
        ConfigurableHashService hashService = new DefaultHashService();
        hashService.setPrivateSalt(ByteSource.Util.bytes(this.staticSalt));
        hashService.setHashAlgorithmName(this.algorithmName);
        hashService.setHashIterations(2);
        HashRequest request = new HashRequest.Builder()
                .setSalt(dynaSalt)
                .setSource(encodedPassword)
                .build();
        String res =  hashService.computeHash(request).toHex();
        System.out.println(res);
    }
}

测试结果

11464886-d6735f03bbdfdfe5.png

使用test/123456登录成功(加盐密码可用)

说明:

除此之外如果我们要自定义加密类型,就需要实现org.springframework.security.crypto.password.PasswordEncoder接口,并且把类名配置在passwordEncoder.type

这种方式我们在这里就不做尝试了,接下来我们结合SpringSecurity提供的加密方法,完成自定义认证校验策略(推荐使用

<think>好的,我现在需要在CAS 5.3.2中实现自定义返回信息,以便通知客户端。首先,我需要了解CAS的基本架构和扩展机制。CAS使用Spring框架,因此自定义功能通常涉及扩展现有组件或实现特定接口。 查阅资料发现,CAS中的认证处理流程可以通过覆盖`AuthenticationHandler`或修改事件监听器来干预。例如,在认证成功或失败时,可以添加自定义逻辑来生成响应消息[^1]。可能需要关注`serviceTicketAction`或`AuthenticationManager`的相关类。 另外,CAS的返回信息通常与Service Ticket和TicketGranting Ticket的生成有关。要修改返回给客户端的消息,可能需要自定义`ServiceTicketGenerator`或调整CAS的REST配置[^2]。此外,CAS使用消息绑定文件(如messages.properties)进行国际化,但直接修改这些文件可能不足以满足复杂需求,因此需要更深入的定制。 考虑到CAS的协议兼容性(如CAS协议、OAuth、SAML),自定义响应必须符合协议规范,避免破坏客户端解析。例如,在CAS协议中,认证成功的响应包含特定XML元素,可以通过扩展`CasProtocolResponseBuilder`来添加自定义字段[^3]。 实现步骤可能包括:1. 创建自定义的`ResponseBuilder`类,覆盖默认的响应生成逻辑;2. 在Spring配置中注册该类以替换默认实现;3. 测试自定义响应是否符合预期,并确保协议兼容性。需要注意CAS的版本差异,5.3.2可能存在特定的配置方式,需参考官方文档或社区资源[^4]。 最后,验证自定义功能是否生效,可以通过日志调试或使用CAS客户端进行测试。可能需要处理异常情况,如网络错误或无效参数,确保自定义响应在各种场景下稳定可靠。</think>在CAS 5.3.2中实现自定义响应消息传递给客户端,可以通过以下步骤完成: ### 一、扩展认证处理器 1. **继承`AbstractAuthenticationHandler`** 重写`authenticateCredential`方法,在认证逻辑中添加自定义属性: ```java public class CustomAuthenticationHandler extends AbstractAuthenticationHandler { @Override public AuthenticationHandlerResult authenticateCredential(final Credential credential) { // 执行原认证逻辑 final AuthenticationHandlerResult result = super.authenticateCredential(credential); // 添加自定义消息 result.getPrincipal().getAttributes().put("customMsg", "认证成功,但需二次验证"); return result; } } ``` ### 二、修改服务端响应生成 2. **自定义CAS协议响应** 创建`CustomCas30ServiceTicketValidator`,继承`Cas30ServiceTicketValidator`,覆盖`buildResponse`方法: ```java protected String buildResponse(final Assertion assertion, final String serviceUrl) { final String baseResponse = super.buildResponse(assertion, serviceUrl); // 插入自定义节点 return baseResponse.replace("</cas:authenticationSuccess>", "<cas:customMessage>需要客户端处理的附加信息</cas:customMessage></cas:authenticationSuccess>"); } ``` ### 三、配置Spring Bean 3. **注册自定义组件** 在`cas-servlet.xml`中添加: ```xml <bean id="customTicketValidator" class="com.example.CustomCas30ServiceTicketValidator" p:httpClient-ref="httpClient" p:casServerUrlPrefix="${cas.server.prefix}"/> ``` ### 、客户端适配处理 4. **客户端解析扩展字段** 在CAS客户端代码中,修改响应解析逻辑以提取自定义消息: ```java Element customMsgElement = (Element)authSuccessElement.getElementsByTagName("cas:customMessage").item(0); String customMsg = customMsgElement.getTextContent(); ``` ### 实现要点说明 - **协议兼容性**:必须严格遵循CAS协议XML结构,自定义字段应添加在`authenticationSuccess`节点下 - **属性传递链路**:需确保自定义属性从认证阶段传递到票据生成阶段,可借助`PrincipalAttributesRepository`配置 - **安全过滤**:应对自定义消息内容进行XSS过滤,避免注入攻击
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值