自定义验证
通常我们密码是加密后存放在数据库中的,那么CAS服务登录时,就要用自定义的校验规则。
增加CustomPasswordEncoder.java,继承AbstractJdbcUsernamePasswordAuthenticationHandler,重写authenticateUsernamePasswordInternal()方法
/** * 自定义加密类 */ public class CustomPasswordEncoder extends AbstractJdbcUsernamePasswordAuthenticationHandler { private String sql; public CustomPasswordEncoder(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order, DataSource dataSource) { super(name, servicesManager, principalFactory, order, dataSource); } @Override protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException, PreventedException { String username = credential.getUsername(); String password = credential.getPassword(); // 查询数据库中的信息 final SysUser user = getJdbcTemplate().queryForObject(sql, new RowMapper<SysUser>() { @Override public SysUser mapRow(ResultSet rs, int rowNum) throws SQLException { SysUser sysUser = new SysUser(); sysUser.setPassword(rs.getString("pwd")); return sysUser; } }, username, username, username); // 输入的密码和数据库中的密码校验, if (!password.equals(user.getPassword())) { throw new GeneralSecurityException("密码不正确"); } // 验证成功,可自定义返回给客户端的多个属性信息 HashMap<String, Object> returnInfo = new HashMap<>(); returnInfo.put("username", username); returnInfo.put("password", password); returnInfo.put("email", user.getEmail()); final List<MessageDescriptor> list = new ArrayList<>(); return this.createHandlerResult(credential, this.principalFactory.createPrincipal(username, returnInfo), list); } }
增加MyAuthenticationHandlerPlanConfigurer.java,实现AuthenticationEventExecutionPlanConfigurer。
public class MyAuthenticationHandlerPlanConfigurer implements AuthenticationEventExecutionPlanConfigurer { private ServicesManager servicesManager; private DataSource dataSource; private String sql; /** * 注册CustomPasswordEncoder,提供SQL,DataSource等信息 */ public AuthenticationHandler myAuthenticationHandler(){ CustomPasswordEncoder customPasswordEncoder = new CustomPasswordEncoder(CustomPasswordEncoder.class.getSimpleName(), servicesManager, new DefaultPrincipalFactory(), 1, dataSource); customPasswordEncoder.setSql(sql); return customPasswordEncoder; } @Override public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) { plan.registerAuthenticationHandler(myAuthenticationHandler()); } }
上面两个文件可以打包全量替换,也可以编译之后将单独放到tomcat的对应目录中。
到tomcat\webapps\cas\WEB-INF\classes目录下找到deployerConfigContext.xml文件
在deployerConfigContext.xml注册MyAuthenticationHandlerPlanConfigurer和数据源信息。在
标签中填写注册: <beans> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://IP:Port/库名?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=UTC" /> <property name="username" value="账号" /> <property name="password" value="密码"/> </bean> <bean class="com.webstudio.sso.MyAuthenticationHandlerPlanConfigurer"> <property name="dataSource" ref="dataSource" /> <property name="servicesManager" ref="servicesManager" /> <property name="sql" value="select * from sys_user where account = ?" /> </bean> </beans>
启动tomcat,就可以用自定义的校验规则校验了。