这个是5.2版本的,5.2和5.1有一点区别,但是区别不大,只是注册表单的地方,有点区别。自定义表单,为啥有这个需求呢,就比如我们表单不止需要有用户名,密码,还需要有系统的信息,这样,就需要自定义表单的方式来完成了这个是cas5.2.x版本,同5.1.x版本不适用。。
代码地址
https://gitee.com/yellowcong/springboot_cas/tree/master/cas-server-form/5.2.x/cas-server-form
目录结构
表单添加
1、创建表单
表单对象,需要继承默认的RememberMeUsernamePasswordCredential
,添加用户所需要的字段,我现在需要加上一个部门的字段信息。
package com.yellowcong.auth;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apereo.cas.authentication.RememberMeUsernamePasswordCredential;
import javax.validation.constraints.Size;
/**
* 用户名,密码,系统
* @author yellowcong
* 创建日期:2018/02/06
*
*/
public class UsernamePasswordSysCredential extends RememberMeUsernamePasswordCredential {
/**
*
*/
private static final long serialVersionUID = 1L;
@Size(min = 2, message = "require system")
private String system;
public String getSystem() {
return system;
}
public UsernamePasswordSysCredential setSystem(String system) {
this.system = system;
return this;
}
@Override
public int hashCode() {
return new HashCodeBuilder().appendSuper(super.hashCode()).append(this.system).toHashCode();
}
}
2、添加参数配置器
参数创建好了,需要配置到我们想要绑定的表单对象以及页面上。表单配置,需要继承AbstractCasWebflowConfigurer
类,然后复写里面的doInitialize方法
package com.yellowcong.auth;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.flow.configurer.AbstractCasWebflowConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.Flow;
import org.springframework.webflow.engine.ViewState;
import org.springframework.webflow.engine.builder.BinderConfiguration;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
/**
* 重新定义默认的web流程
* @author yellowcong
* 创建日期:2018/02/06
*
*/
public class CustomWebflowConfigurer extends AbstractCasWebflowConfigurer {
public CustomWebflowConfigurer(FlowBuilderServices flowBuilderServices,
FlowDefinitionRegistry loginFlowDefinitionRegistry, ApplicationContext applicationContext,
CasConfigurationProperties casProperties) {
super(flowBuilderServices, loginFlowDefinitionRegistry, applicationContext, casProperties);
}
@Override
protected void doInitialize() {
final Flow flow = getLoginFlow();
bindCredential(flow);
}
/**
* 绑定输入信息
*
* @param flow
*/
protected void bindCredential(Flow flow) {
//重写绑定自定义credential
//表单对象,就是这个 credential
createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, UsernamePasswordSysCredential.class);
//获取登录页
final ViewState state = (ViewState) flow.getState(CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM);
//获取参数绑定对象
final BinderConfiguration cfg = getViewStateBinderConfiguration(state);
//由于用户名以及密码已经绑定,所以只需对新加系统参数绑定即可
//参数1 :字段名
//参数2 :转换器
//参数3 :是否必须的字段
cfg.addBinding(new BinderConfiguration.Binding("system", null, false));
}
}
3、配置到springboot中
在cas5.2.x版本和cas5.1.x版本,就这个地方有区别,而且表单配置的那个类,够着函数也是有所区别的。
package com.yellowcong.config;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConfigurer;
import org.apereo.cas.web.flow.config.CasWebflowContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
import com.yellowcong.auth.CustomWebflowConfigurer;
/**
* @author Carl
* @date 2017/10/23
* @since 1.6.0
*/
@Configuration("customerAuthWebflowConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
@AutoConfigureBefore(value = CasWebflowContextConfiguration.class)
public class CustomerAuthWebflowConfiguration {
@Autowired
private CasConfigurationProperties casProperties;
@Autowired
@Qualifier("loginFlowRegistry")
private FlowDefinitionRegistry loginFlowRegistry;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private FlowBuilderServices flowBuilderServices;
/**
* 注册我们的表单到服务器上
* @return
*/
@Bean
public CasWebflowConfigurer customWebflowConfigurer() {
//实例化自定义的表单配置类
final CustomWebflowConfigurer c = new CustomWebflowConfigurer(flowBuilderServices, loginFlowRegistry,
applicationContext, casProperties);
//初期化
c.initialize();
//返回对象
return c;
}
}
表单验证器
1、创建表单处理类
需要继承AbstractPreAndPostProcessingAuthenticationHandler
这个类,这个地方我添加的规则是只要是UsernamePasswordSysCredential
类型的表单,我们才能处理,而且处理逻辑是,用户名是yellowcong,系统是sso的,才可以登录
package com.yellowcong.auth.handler;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.HandlerResult;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import com.yellowcong.auth.UsernamePasswordSysCredential;
import javax.security.auth.login.AccountNotFoundException;
import java.security.GeneralSecurityException;
import java.util.Collections;
/**
* 用户名系统认证,只要是admin用户加上sso系统就允许通过
* @author yellowcong
* 创建日期:2018/02/06
*
*/
public class UsernamePasswordSystemAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
public UsernamePasswordSystemAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
super(name, servicesManager, principalFactory, order);
}
@Override
protected HandlerResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
//当用户名为admin,并且system为sso即允许通过
UsernamePasswordSysCredential sysCredential = (UsernamePasswordSysCredential) credential;
if ("yellowcong".equals(sysCredential.getUsername()) && "sso".equals(sysCredential.getSystem())) {
//这里可以自定义属性数据
return createHandlerResult(credential, this.principalFactory.createPrincipal(((UsernamePasswordSysCredential) credential).getUsername(), Collections.emptyMap()), null);
} else {
throw new AccountNotFoundException("必须是yellowcong这样的用户才允许通过");
}
}
@Override
public boolean supports(Credential credential) {
return credential instanceof UsernamePasswordSysCredential;
}
}
2、注册到springboot
注册验证器到springboot中。
package com.yellowcong.config;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer;
import org.apereo.cas.authentication.AuthenticationHandler;
import org.apereo.cas.authentication.principal.DefaultPrincipalFactory;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.services.ServicesManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.yellowcong.auth.handler.UsernamePasswordSystemAuthenticationHandler;
/**
* @author yellowcong
* 创建日期:2018/02/06
*
*/
@Configuration("customAuthenticationEventExecutionPlanConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CustomAuthenticationEventExecutionPlanConfiguration implements AuthenticationEventExecutionPlanConfigurer {
@Autowired
@Qualifier("servicesManager")
private ServicesManager servicesManager;
/**
* 注册验证器
*
* @return
*/
@Bean
public AuthenticationHandler customAuthenticationHandler() {
//优先验证
return new UsernamePasswordSystemAuthenticationHandler("customAuthenticationHandler",
servicesManager, new DefaultPrincipalFactory(), 1);
}
//注册自定义认证器
@Override
public void configureAuthenticationExecutionPlan(final AuthenticationEventExecutionPlan plan) {
plan.registerAuthenticationHandler(customAuthenticationHandler());
}
}
添加到spring.factories
为了让springboot知道我们添加了哪些配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yellowcong.config.CustomerAuthWebflowConfiguration,\
com.yellowcong.config.CustomAuthenticationEventExecutionPlanConfiguration
启动服务
#普通方式启动
build.cmd run
#debug方式启动
build.cmd debug
登录验证
我们从8888客户端登录系统,然后我们先用了yellowcong用户密码瞎打的,最后系统类型,没选单点登录,结果登录失败,如果用户名yellowcong,并且是sso系统,就可以直接扽登录了。
常见问题
1、找不到org.apereo.cas.configuration类
我只能说是个bug,需要单独导入这个包到系统中,就解决问题了
解决办法,就是导入一个jar包到工程目录。
<!-- 单独导入cas的配置依赖到项目中 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-configuration</artifactId>
<version>${cas.version}</version>
<scope>system</scope>
<optional>true</optional>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/cas-server-core-configuration-${cas.version}.jar</systemPath>
</dependency>
2、Failed to clean project: Failed to delete
出现这个问题,就是target目录有占用,mvn的命令工具删除不掉里面的数据,所以只能手动解锁,删除里面的数据。
参考文章
https://apereo.github.io/cas/5.2.x/installation/Webflow-Customization-Extensions.html