2、cas服务端自定义密码加密方式
3、cas服务端自定义主题,也就是登录页面,也可以其他的页面
4、cas服务端在登录时提交的表单中添加字段
5、cas服务端自定义登录校验
6、cas服务端自定义返回异常
7、cas服务端使用ajax进行登录 环境:
CAS版本:5.3
下载链接:git地址是:https://github.com/apereo/cas-overlay-template
tomcat:8
jdk:1.8
1、先把cas服务端的源代码拷贝出来,方法如下:
1)使用idea打开
红框中是通过idea配置tomcat后,编译出来的代码。
2)创建src目录,如下,并且把target/cas/meta-INF文件、target/cas/services、target/cas/application.properties,这三个文件拷贝到resources中。
由于CAS默认支持https,如果想要改成支持http,获取一些其他CAS服务端的基本配置,那么可以看这篇文章:SSO单点登录(一)创建CAS服务端_我是混IT圈的-CSDN博客_cas服务器搭建
1、cas服务端配置mysql1、pom.xml
org.apereo.cas
cas-server-support-jdbc
${cas.version}
org.apereo.cas
cas-server-support-jdbc-drivers
${cas.version}
mysql
mysql-connector-java
5.1.38
2、application.properties 配置文件
1)添加与mysql的链接
cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/shiro?useUnicode=true&characterEncoding=utf-8 cas.authn.jdbc.query[0].user=root #数据库账号 cas.authn.jdbc.query[0].password=123456 #数据库密码 cas.authn.jdbc.query[0].sql=select password from system_admin_user where account = ? #表的查询sql cas.authn.jdbc.query[0].fieldPassword=password #表中属于密码的字段
2)注释掉cas默认的帐号密码,不然这个账号密码也是可以登录的
#cas.authn.accept.users=casuser::Mellon
注意:这里使用mysql进行登录,密码是没有经过加密的,比如,登录密码是123456,那么数据库的密码就是123456。
2、cas服务端自定义密码加密方式1、创建类:MyPasswordEncoder
package com.example.cas.password;
import org.springframework.security.crypto.password.PasswordEncoder;
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
System.out.println("encode===========用户输入的密码:" + charSequence);
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String str) {
//charSequence 为用户输入的密码
System.out.println("matches---------------用户输入的密码:"+charSequence);
//str 为数据库密码
System.out.println("matches---------------数据库密码:"+str);
if (charSequence.equals(str)){
return true;
}
return false;
}
}
2、application.properties 配置文件
#开启自定义密码验证 cas.authn.jdbc.query[0].passwordEncoder.type=com.example.cas.MyPasswordEncoder3、cas服务端自定义主题,也就是登录页面,也可以其他的页面
1、pom.xml
org.apereo.cas
cas-server-core-webflow
${cas.version}
org.apereo.cas
cas-server-core-webflow-api
${cas.version}
2、注册 json,resources 下创建 services/login-10000001.json,主题名称为 loginTheme
{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "^(https|http|imaps)://.*",
"name" : "web",
"id" : 10000001,
"evaluationOrder" : 10,
"accessStrategy" : {
"@class" : "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
"enabled" : true,
"ssoEnabled" : true
},
"theme": "loginTheme"
}
3、配置文件:application.properties 开启json扫码
# Service Registry(服务注册) # 开启识别Json文件,默认false,这里就是开启识别 services 中的json文件的 cas.serviceRegistry.initFromJson=true #自动扫描服务配置,默认开启 cas.serviceRegistry.watcherEnabled=true #120秒扫描一遍 cas.serviceRegistry.schedule.repeatInterval=120000 #延迟15秒开启 # cas.serviceRegistry.schedule.startDelay=15000 cas.serviceRegistry.json.location=classpath:/services #JSON文件主题名称 loginTheme cas.theme.defaultThemeName=loginTheme
4、在resources下创建 loginTheme.properties
loginTheme.javascript.file=/themes/loginTheme/js/cas.js loginTheme.standard.css.file=/themes/loginTheme/css/cas.css loginTheme.login.images.path=/themes/loginTheme/images cas.standard.css.file=/css/cas.css cas.javascript.file=/js/cas.js cas.admin.css.file=/css/admin.css
创建静态资源和登录文件,路径如下:
# 静态资源文件 resources/static/themes/loginTheme/css/cas.css resources/static/themes/loginTheme/js/cas.js resources/static/themes/loginTheme/images/ # 登录页面 resources/templates/loginTheme/casLoginView.html
5、casLoginView.html:名称是固定的,不能瞎干,页面内容可以自己些,下面这个页面是拷贝的cas登录页面。
Title
登录页面
4、cas服务端在登录时提交的表单中添加字段
在登录表单中添加字段
1、创建接受表单中新增的字段的类:CustomCredential
package com.example.cas.login;
import org.apereo.cas.authentication.UsernamePasswordCredential;
public class CustomCredential extends UsernamePasswordCredential {
private String telephone;
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
}
2、添加自定义字段类:CustomWebflowConfigurer
package com.example.cas.config;
import com.example.cas.login.CustomCredential;
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;
public class CustomWebflowConfigurer extends AbstractCasWebflowConfigurer {
public CustomWebflowConfigurer(FlowBuilderServices flowBuilderServices,
FlowDefinitionRegistry flowDefinitionRegistry,
ApplicationContext applicationContext,
CasConfigurationProperties casProperties) {
super(flowBuilderServices, flowDefinitionRegistry, applicationContext, casProperties);
}
@Override
protected void doInitialize() {
final Flow flow = super.getLoginFlow();
bindCredential(flow);
}
protected void bindCredential(Flow flow) {
// 重写绑定自定义credential
createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, CustomCredential.class);
//登录页绑定新参数
final ViewState state = (ViewState) flow.getState(CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM);
final BinderConfiguration cfg = getViewStateBinderConfiguration(state);
// 由于用户名以及密码已经绑定,所以只需对新加系统参数绑定即可
// 字段名,转换器,是否必须字段 telephone:它是新添加的字段,可以添加多个字段
cfg.addBinding(new BinderConfiguration.Binding("telephone", null, true));
cfg.addBinding(new BinderConfiguration.Binding("phone", null, true));
}
}
3、配置 添加自定义字段 类:CustomerAuthWebflowConfiguration
package com.example.cas.config;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConfigurer;
import org.apereo.cas.web.flow.CasWebflowExecutionPlan;
import org.apereo.cas.web.flow.CasWebflowExecutionPlanConfigurer;
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.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;
@Configuration("customerAuthWebflowConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CustomerAuthWebflowConfiguration implements CasWebflowExecutionPlanConfigurer {
@Autowired
private CasConfigurationProperties casProperties;
@Autowired
@Qualifier("loginFlowRegistry")
private FlowDefinitionRegistry loginFlowDefinitionRegistry;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private FlowBuilderServices flowBuilderServices;
@Bean
public CasWebflowConfigurer customWebflowConfigurer() {
//实例化自定义的表单配置类
final CustomWebflowConfigurer c = new CustomWebflowConfigurer(flowBuilderServices, loginFlowDefinitionRegistry,
applicationContext, casProperties);
// 初始化
c.initialize();
// 返回对象
return c;
}
@Override
public void configureWebflowExecutionPlan(final CasWebflowExecutionPlan plan) {
plan.registerWebflowConfigurer(customWebflowConfigurer());
}
}
4、在文件 resources/meta-INF/spring.factories 中,添加配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.cas.config.CustomerAuthWebflowConfiguration5、cas服务端自定义登录校验
1、pom.xml
org.apereo.cas
cas-server-support-json-service-registry
${cas.version}
org.apereo.cas
cas-server-core-authentication-api
${cas.version}
org.apereo.cas
cas-server-core-configuration-api
${cas.version}
2、自定义校验类:CustomUsernamePasswordAuthentication
package com.example.cas.login;
import com.example.cas.Model.UserInfo;
import com.example.cas.Model.CustomCredential;
import org.apereo.cas.authentication.*;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.security.auth.login.AccountLockedException;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class CustomUsernamePasswordAuthentication extends AbstractPreAndPostProcessingAuthenticationHandler {
public CustomUsernamePasswordAuthentication(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
super(name, servicesManager, principalFactory, order);
}
@Override
public boolean supports(Credential credential) {
//判断传递过来的Credential 是否是自己能处理的类型
return credential instanceof CustomCredential;
}
@Override
protected AuthenticationHandlerExecutionResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
System.out.println("++========================="+4);
UsernamePasswordCredential usernamePasswordCredential = (UsernamePasswordCredential) credential;
String username = usernamePasswordCredential.getUsername();
String password = usernamePasswordCredential.getPassword();
System.out.println("******CustomUsernamePasswordAuthentication******:" + username);
System.out.println("******CustomUsernamePasswordAuthentication******:" + password);
// JDBC模板依赖于连接池来获得数据的连接,所以必须先要构造连接池
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/shiro?useUnicode=true&characterEncoding=utf-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 创建JDBC模板
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
String sql = "SELECt * FROM system_admin_user WHERe account = ?";
UserInfo info = (UserInfo) jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper(UserInfo.class));
System.out.println("database username : "+ info.getAccount());
System.out.println("database password : "+ info.getPassword());
//这里的异常还不行,用不了的
if (info != null) {
throw new AccountLockedException();
}
if (!info.getPassword().equals(password)) {
throw new FailedLoginException("Sorry, 密码不正确!");
} else {
//可自定义返回给客户端的多个属性信息
HashMap returnInfo = new HashMap<>();
returnInfo.put("id", info.getId());
returnInfo.put("account", info.getAccount());
returnInfo.put("disableStatus", info.getDisableStatus());
final List list = new ArrayList<>();
return createHandlerResult(usernamePasswordCredential, this.principalFactory.createPrincipal(username, returnInfo), list);
}
}
}
3、注入配置 CustomAuthenticationConfiguration
package com.example.cas.login;
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.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration("CustomAuthenticationConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CustomAuthenticationConfiguration implements AuthenticationEventExecutionPlanConfigurer {
@Autowired
private ServicesManager servicesManager;
@Bean
public AuthenticationHandler myAuthenticationHandler() {
// 参数: name, servicesManager, principalFactory, order
// 定义为优先使用它进行认证
return new CustomUsernamePasswordAuthentication(CustomUsernamePasswordAuthentication.class.getName(),
servicesManager, new DefaultPrincipalFactory(), 1);
}
@Override
public void configureAuthenticationExecutionPlan(final AuthenticationEventExecutionPlan plan) {
plan.registerAuthenticationHandler(myAuthenticationHandler());
}
}
4、在文件 resources/meta-INF/spring.factories 中,添加配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.cas.login.CustomAuthenticationConfiguration
注意:上面自定义登录中的异常返回,是不行的。
6、cas服务端自定义返回异常7、cas服务端使用ajax进行登录
这两个目录没有时间搞了。



