Cas5.3.2之自定义登入流程(实现验证码)
自定义验证很重要,因为我们后续的很多功能,都是基于自定义验证。
CAS服务器的org.apereo.cas.authentication.AuthenticationManager负责基于提供的凭证信息进行用户认证。与Spring Security很相似,实际的认证委托给了一个或多个实现了org.apereo.cas.authentication.AuthenticationHandler接口的处理类。在cas的认证过程中逐个执行authenticationHandlers中配置的认证管理,直到有一个成功为止。
CAS内置了一些AuthenticationHandler实现类,如下图所示,QueryDatabaseAuthenticationHandler中提供了基于jdbc的用户认
如果需要实现自定义登录,只需要实现org.apereo.cas.authentication.AuthenticationHandler接口即可。当然也可以利用已有的实现,比如创建一个继承自org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler的类。下面我们就来实现自定义验证。
自定义登入
pom.xml 添加如下依赖jar包
<!--自定义用户登入依赖集成 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-webflow</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-authentication</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-authentication-api</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-webflow-api</artifactId>
<version>${cas.version}</version>
</dependency>
自定义验证类,继承AbstractPreAndPostProcessingAuthenticationHandler
package com.digipower.authentication.handler;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.FailedLoginException;
import org.apache.commons.lang.StringUtils;
import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.MessageDescriptor;
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 org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.digipower.encrypt.PasswordEncryption;
import com.digipower.exception.CaptchaException;
import com.digipower.verification.code.UsernamePasswordCaptchaCredential;
/**
* 自定义用户认证核心代码
* @author zzg
*
*/
public class UsernamePasswordCaptchaAuthenticationHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
public UsernamePasswordCaptchaAuthenticationHandler(String name, ServicesManager servicesManager,
PrincipalFactory principalFactory, Integer order) {
super(name, servicesManager, principalFactory, order);
// TODO Auto-generated constructor stub
}
@Override
protected AuthenticationHandlerExecutionResult doAuthentication(Credential credential)
throws GeneralSecurityException, PreventedException {
// TODO Auto-generated method stub
// 用户凭证
UsernamePasswordCaptchaCredential myCredential = (UsernamePasswordCaptchaCredential) credential;
String requestCaptcha = myCredential.getCaptcha();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
Object attribute = attributes.getRequest().getSession().getAttribute("captcha");
String realCaptcha = attribute == null ? null : attribute.toString();
if (StringUtils.isBlank(requestCaptcha) || !requestCaptcha.equalsIgnoreCase(realCaptcha)) {
throw new CaptchaException("验证码错误");
}
// 验证用户名和密码
DriverManagerDataSource d = new DriverManagerDataSource();
d.setDriverClassName("com.mysql.jdbc.Driver");
d.setUrl(
"jdbc:mysql://192.168.1.73:3306/boot-security?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true");
d.setUsername("root");
d.setPassword("digipower");
JdbcTemplate template = new JdbcTemplate();
template.setDataSource(d);
// 查询数据库加密的的密码
Map<String, Object> user = template.queryForMap("select pswd from u_user where nickname = ?",
myCredential.getUsername());
if (user == null) {
throw new AccountNotFoundException("用户名输入错误或用户名不存在");
}
// 返回多属性
Map<String, Object> map = new HashMap<>();
map.put("username", myCredential.getUsername());
// 密码加密验证(MD5 32位 大写)
PasswordEncryption passwordEncryption = new PasswordEncryption();
List<MessageDescriptor> warning = new ArrayList<MessageDescriptor>();
if (passwordEncryption.matches(myCredential.getPassword(), user.get("pswd").toString())) {
return createHandlerResult(myCredential, principalFactory.createPrincipal(myCredential.getUsername(), map),
warning);
}
throw new FailedLoginException("密码输入错误");
}
// 判断是否支持自定义用户登入凭证
@Override
public boolean supports(Credential credential) {
// TODO Auto-generated method stub
return credential instanceof UsernamePasswordCaptchaCredential;
}
}
绑定自定义认证流程和自定义凭证信息
package com.digipower.captcha.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.digipower.authentication.handler.UsernamePasswordCaptchaAuthenticationHandler;
/**
* 自定义用户登入流程使用的自定义的用户凭证
* @author zzg
*
*/
@Configuration("usernamePasswordCaptchaConfig")
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class UsernamePasswordCaptchaConfig implements AuthenticationEventExecutionPlanConfigurer{
@Autowired
private CasConfigurationProperties casProperties;
@Autowired
@Qualifier("servicesManager")
private ServicesManager servicesManager;
/**
* 用户定义用户登入处理器
* @return
*/
@Bean
public AuthenticationHandler rememberMeUsernamePasswordCaptchaAuthenticationHandler() {
UsernamePasswordCaptchaAuthenticationHandler handler = new UsernamePasswordCaptchaAuthenticationHandler(
UsernamePasswordCaptchaAuthenticationHandler.class.getSimpleName(),
servicesManager,
new DefaultPrincipalFactory(),
9);
return handler;
}
/**
*
* <p>Title: configureAuthenticationExecutionPlan</p>
* <p>Description: 用户自定义表单处理注册 </p>
* @param plan
* @see org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer#configureAuthenticationExecutionPlan(org.apereo.cas.authentication.AuthenticationEventExecutionPlan)
*/
@Override
public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) {
// TODO Auto-generated method stub
plan.registerAuthenticationHandler(rememberMeUsernamePasswordCaptchaAuthenticationHandler());
}
}
创建用户登入凭证,添加验证码属性
package com.digipower.verification.code;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apereo.cas.authentication.RememberMeUsernamePasswordCredential;
/**
* 自定义用户凭证,添加验证码属性
* @author zzg
*
*/
@SuppressWarnings("serial")
public class UsernamePasswordCaptchaCredential extends RememberMeUsernamePasswordCredential {
private String captcha;
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.appendSuper(super.hashCode())
.append(this.captcha)
.toHashCode();
}
}
重新定义Apereo Cas5 服务端的登入流程
package com.digipower.webflow.action;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.flow.configurer.DefaultLoginWebflowConfigurer;
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;
import com.digipower.verification.code.UsernamePasswordCaptchaCredential;
/**
* 自定义系统登入设置自定义用户凭证
* @author zzg
*
*/
public class CaptchaWebflowConfigurer extends DefaultLoginWebflowConfigurer {
public CaptchaWebflowConfigurer(FlowBuilderServices flowBuilderServices,
FlowDefinitionRegistry flowDefinitionRegistry, ApplicationContext applicationContext,
CasConfigurationProperties casProperties) {
super(flowBuilderServices, flowDefinitionRegistry, applicationContext, casProperties);
}
@Override
protected void createRememberMeAuthnWebflowConfig(Flow flow) {
if (casProperties.getTicket().getTgt().getRememberMe().isEnabled()) {
createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, UsernamePasswordCaptchaCredential.class);
final ViewState state = getState(flow, CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM, ViewState.class);
final BinderConfiguration cfg = getViewStateBinderConfiguration(state);
cfg.addBinding(new BinderConfiguration.Binding("rememberMe", null, false));
cfg.addBinding(new BinderConfiguration.Binding("captcha", null, true));
} else {
createFlowVariable(flow, CasWebflowConstants.VAR_ID_CREDENTIAL, UsernamePasswordCaptchaCredential.class);
final ViewState state = getState(flow, CasWebflowConstants.STATE_ID_VIEW_LOGIN_FORM, ViewState.class);
final BinderConfiguration cfg = getViewStateBinderConfiguration(state);
// cfg.addBinding(new BinderConfiguration.Binding("rememberMe", null, false));
cfg.addBinding(new BinderConfiguration.Binding("captcha", null, true));
}
}
}
修改Apereo Cas 5 系统自带的登入流程定义webflow
在login-webflow.xml/viewLoginForm 添加如下代码:
<binding property="captcha" required="false"/>
源码修改如下:
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/webflow"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow.xsd">
<action-state id="initializeLoginForm">
<evaluate expression="initializeLoginAction" />
<transition on="success" to="viewLoginForm"/>
</action-state>
<view-state id="viewLoginForm" view="casLoginView" model="credential">
<binder>
<binding property="username" required="true"/>
<binding property="password" required="true"/>
<binding property="captcha" required="false"/>
</binder>
<transition on="submit" bind="true" validate="true" to="realSubmit" history="invalidate"/>
</view-state>
<action-state id="realSubmit">
<evaluate expression="authenticationViaFormAction"/>
<transition on="warn" to="warn"/>
<transition on="success" to="createTicketGrantingTicket"/>
<transition on="successWithWarnings" to="showAuthenticationWarningMessages"/>
<transition on="authenticationFailure" to="handleAuthenticationFailure"/>
<transition on="error" to="initializeLoginForm"/>
</action-state>
</flow>
将自定义登入流程添加如Apereo Cas 5服务器中webflow 中
package com.digipower.captcha.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.digipower.webflow.action.CaptchaWebflowConfigurer;
/**
* 自定义登入流程配置入webflow
* @author zzg
*
*/
@Configuration("captchaWebflowConfigurer")
@EnableConfigurationProperties(CasConfigurationProperties.class)
@AutoConfigureBefore(value = CasWebflowContextConfiguration.class)
public class CaptchaConfigurer {
@Autowired
@Qualifier("loginFlowRegistry")
private FlowDefinitionRegistry loginFlowRegistry;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private CasConfigurationProperties casProperties;
@Autowired
private FlowBuilderServices flowBuilderServices;
@Bean("defaultLoginWebflowConfigurer")
public CasWebflowConfigurer defaultLoginWebflowConfigurer() {
CasWebflowConfigurer c = new CaptchaWebflowConfigurer(flowBuilderServices, loginFlowRegistry,
applicationContext, casProperties);
c.initialize();
return c;
}
}
补充相关的工具类:Kaptcha 图形验证码初始化,用户密码加密工具类,springBean 工具类和相关自定义异常
package com.digipower.kaptcha.config;
import javax.servlet.ServletException;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.code.kaptcha.servlet.KaptchaServlet;
@Configuration
public class KaptchaConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean() throws ServletException {
ServletRegistrationBean servlet = new ServletRegistrationBean(new KaptchaServlet(), "/kaptcha.jpg");//加载路径
servlet.addInitParameter("kaptcha.border", "no"/* kborder */);// 无边框
servlet.addInitParameter("kaptcha.session.key", "captcha");// session key
servlet.addInitParameter("kaptcha.textproducer.font.color", "black");
servlet.addInitParameter("kaptcha.textproducer.font.size", "25");
servlet.addInitParameter("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
servlet.addInitParameter("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");
servlet.addInitParameter("kaptcha.image.width", "90");
servlet.addInitParameter("kaptcha.image.height", "33");
servlet.addInitParameter("kaptcha.textproducer.char.length", "4");
servlet.addInitParameter("kaptcha.textproducer.char.space", "5");
servlet.addInitParameter("kaptcha.background.clear.from", "247,247,247"); // 和登录框背景颜色一致
servlet.addInitParameter("kaptcha.background.clear.to", "247,247,247");
return servlet;
}
}
package com.digipower.encrypt;
import org.apache.commons.codec.digest.DigestUtils;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* 自定义数据密码加密工具类
* @author zzg
*
*/
public class PasswordEncryption implements PasswordEncoder{
@Override
public String encode(CharSequence password) {
return DigestUtils.md5Hex(password.toString()).toUpperCase();
}
@Override
public boolean matches(CharSequence rawPassword, String encodePassword) {
// 判断密码是否存在
if (rawPassword == null) {
return false;
}
//通过md5加密后的密码
String pass = this.encode(rawPassword.toString());
//比较密码是否相等的问题
return pass.equals(encodePassword);
}
AbstractPreAndPostProcessingAuthenticationHandler handler;
}
package com.digipower.exception;
import javax.security.auth.login.AccountException;
@SuppressWarnings("serial")
public class CaptchaException extends AccountException {
public CaptchaException() {
super();
// TODO Auto-generated constructor stub
}
public CaptchaException(String msg) {
super(msg);
// TODO Auto-generated constructor stub
}
}
package com.digipower.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<?> getType(String name) {
return applicationContext.getType(name);
}
}
加载该配置类
在resources\META-INF\spring.factories中配置该类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.digipower.captcha.config.CaptchaConfigurer,\
com.digipower.kaptcha.config.KaptchaConfig,\
com.digipower.captcha.config.UsernamePasswordCaptchaConfig,\
com.digipower.util.SpringContextUtils
系统登入页面修改,添加验证码(/templates/fragments/loginfrom.html),添加如下代码:
<section class="form-group">
<label for="captcha">验证码</label>
<div>
<input class="required"
type="text"
id="captcha"
size="10"
tabindex="3"
th:field="*{captcha}"
autocomplete="off"/>
<img th:src="@{/kaptcha.jpg}" id="captcha_img" onclick="javascript:refreshCaptcha()" />
<script type="text/javascript">
function refreshCaptcha(){
$("#captcha_img").attr("src","/cas/kaptcha.jpg?id=" + new Date() + Math.floor(Math.random()*24));
}
</script>
</div>
</section>
apereo cas5 自定义项目的整体结构:
pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd ">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-overlay</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>com.rimerosolutions.maven.plugins</groupId>
<artifactId>wrapper-maven-plugin</artifactId>
<version>0.0.5</version>
<configuration>
<verifyDownload>true</verifyDownload>
<checksumAlgorithm>MD5</checksumAlgorithm>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<configuration>
<mainClass>${mainClassName}</mainClass>
<addResources>true</addResources>
<executable>${isExecutable}</executable>
<layout>WAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>cas</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
<recompressZippedFiles>false</recompressZippedFiles>
<archive>
<compress>false</compress>
<manifestFile>${manifestFileToUse}</manifestFile>
</archive>
<overlays>
<overlay>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp${app.server}</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
</plugin>
</plugins>
<finalName>cas</finalName>
</build>
<properties>
<mysql.driver.version>8.0.13</mysql.driver.version>
<cas.version>5.3.9</cas.version>
<springboot.version>1.5.18.RELEASE</springboot.version>
<!-- app.server could be -jetty, -undertow, -tomcat, or blank if you plan
to provide appserver -->
<app.server>-tomcat</app.server>
<mainClassName>org.springframework.boot.loader.WarLauncher</mainClassName>
<isExecutable>false</isExecutable>
<manifestFileToUse>${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF</manifestFileToUse>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>sonatype-releases</id>
<url>http://oss.sonatype.org/content/repositories/releases/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>shibboleth-releases</id>
<url>https://build.shibboleth.net/nexus/content/repositories/releases</url>
</repository>
</repositories>
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<id>default</id>
<dependencies>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp${app.server}</artifactId>
<version>${cas.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<!-- ...Additional dependencies may be placed here... -->
<!-- 数据库 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-jdbc</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-jdbc-drivers</artifactId>
<version>${cas.version}</version>
</dependency>
<!-- Database Authentication End -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
<!-- ticker redis 存储 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-redis-ticket-registry</artifactId>
<version>${cas.version}</version>
</dependency>
<!--自定义用户登入依赖集成 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-webflow</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-authentication</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-authentication-api</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-webflow-api</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-configuration</artifactId>
<version>${cas.version}</version>
</dependency>
<!--验证码工具包 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<!-- 审计功能 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-audit-jdbc</artifactId>
<version>${cas.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
<profile>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<id>exec</id>
<properties>
<mainClassName>org.apereo.cas.web.CasWebApplication</mainClassName>
<isExecutable>true</isExecutable>
<manifestFileToUse></manifestFileToUse>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>echo-maven-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>echo</goal>
</goals>
</execution>
</executions>
<configuration>
<echos>
<echo>Executable profile to make the generated CAS web
application executable.</echo>
</echos>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<id>bootiful</id>
<properties>
<app.server>-tomcat</app.server>
<isExecutable>false</isExecutable>
</properties>
<dependencies>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp${app.server}</artifactId>
<version>${cas.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
<profile>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<id>pgp</id>
<build>
<plugins>
<plugin>
<groupId>com.github.s4u.plugins</groupId>
<artifactId>pgpverify-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<pgpKeyServer>hkp://pool.sks-keyservers.net</pgpKeyServer>
<pgpKeysCachePath>${settings.localRepository}/pgpkeys-cache</pgpKeysCachePath>
<scope>test</scope>
<verifyPomFiles>true</verifyPomFiles>
<failNoSignature>false</failNoSignature>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
效果展示:
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。