服务部署:
环境准备:
JDK: 1.8
cas-overlay-template :5.3.x https://github.com/apereo/cas-overlay-template
maven:3.6.3
导入IDEA,此时会去下载一个依赖:cas-server-webapp-tomcat-5.3.14.war ,具体的版本可以根据IDEA的提示去下载。可以通过以下地址去下载,下载完拷贝到maven仓库就行 :https://repo1.maven.org/maven2/org/apereo/cas/cas-server-webapp-tomcat/5.3.14/
然后再IDEA中执行 mvn clean package 进行打包,打完包后会得到一个 cas.war。把这个war包放到tomcat的webapp目录下,启动tomcat即可。
我这边打包遇到个报错:
删除maven仓库repository文件夹下org/apache/maven下的文件夹,然后重新 maven reimport一下,再重新mvn clean package。
HTTP支持:
这个版本默认是只支撑https请求的(https访问需要配置证书,百度一下),当我们客户端集成shiro,cas-client要整合的时候,发现跳转登录会报不安全之类的信息。这个时候需要我们开启http支持
到tomcat的webapps目录下找到 cas/WEB-INF\classes\application.properties。在cas.authn.accept.users=casuser::Mellon的下面添加如下两行配置。
cas.authn.accept.users=casuser::Mellon cas.tgc.secure=false cas.serviceRegistry.initFromJson=true
WEB-INF\classes\services\HTTPSandIMAPS-10000001.json 中添加http的支持。
{ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https|http|imaps)://.*", "name" : "HTTPS and IMAPS", "id" : 10000001, "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.", "evaluationOrder" : 10000 }
然后启动服务。按照application.properties提供的账号密码 casuser::Mellon 进行登录即可:
CAS连接数据库:
1.在cas-overlay-template项目的pom中添加相关依赖:
<mysql.driver.version>5.1.46</mysql.driver.version>
<!--数据库认证相关 start-->
<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>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
<!--数据库认证相关 end-->
2.然后打包,丢到tomcat中启动。然后找到 webapps目录下找到 cas/WEB-INF\classes\application.properties 。将原来的用户配置注释掉。添加如下信息:
#cas.authn.accept.users=casuser::Mellon cas.authn.jdbc.query[0].url=jdbc:mysql://192.168.1.101:3306/spring-orm1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
cas.authn.jdbc.query[0].user=root cas.authn.jdbc.query[0].password=123456 cas.authn.jdbc.query[0].sql=select * from user where username=? cas.authn.jdbc.query[0].fieldPassword=password cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver
3.在数据库中添加对应表。然后重启tomcat。就可以进行数据库的用户认证登录。
Springboot 整合cas-client:
第三方提供的依赖整合:
1.添加依赖:
<!-- CAS -->
<dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId>
<version>1.5.0-GA</version>
</dependency>
2.修改 application.properties 配置文件:
## CAS 配置 cas.validation-type = CAS #cas服务地址 cas.server-url-prefix = http://localhost:8080/cas
#cas服务登录地址 cas.server-login-url = http://localhost:8080/cas/login
#cas服务登出地址 cas-server-logout-url = http://localhost:8080/cas/logout
#本地服务地址 cas.client-host-url = http://localhost:8888
3.启用服务注解:
@SpringBootApplication @EnableCasClient//开启cas-client
public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
通过上面的三个步骤就可以完成client的自动整合。
手动整合:
1.添加依赖:
<dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.3.3</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency>
2.修改 application.properties 配置:
## CAS 配置 spring.cas.sign-out-filters=/logout spring.cas.auth-filters=/* spring.cas.validate-filters=/* spring.cas.request-wrapper-filters=/* spring.cas.assertion-filters=/* spring.cas.cas-server-login-url=http://localhost:8080/cas/login spring.cas.cas-server-url-prefix=http://localhost:8080/cas spring.cas.redirect-after-validation=true spring.cas.use-session=true spring.cas.server-name=http://localhost:8888
3.添加cas读取配置文件的相关配置类:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; // 获取配置文件中属性值 @Component @ConfigurationProperties(prefix = "spring.cas") public class SpringCasAutoConfig { private static final String separator = ","; private String validateFilters; private String signOutFilters; private String authFilters; private String assertionFilters; private String requestWrapperFilters; private String casServerUrlPrefix; private String casServerLoginUrl; private String serverName; private boolean useSession = true; private boolean redirectAfterValidation = true; // 省略 get / set }
4.添加 cas 配置整合类:
package com.example.demo; import org.jasig.cas.client.authentication.AuthenticationFilter; import org.jasig.cas.client.session.SingleSignOutFilter; import org.jasig.cas.client.session.SingleSignOutHttpSessionListener; import org.jasig.cas.client.util.AssertionThreadLocalFilter; import org.jasig.cas.client.util.HttpServletRequestWrapperFilter; import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; @Configuration public class CasConfig { // 是否启用CAS private static boolean casEnabled = true; @Autowired private SpringCasAutoConfig autoConfig; /** * 用于实现单点登出功能 */ @Bean public ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> singleSignOutHttpSessionListener() { ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> listener = new ServletListenerRegistrationBean<>(); listener.setEnabled(casEnabled); listener.setListener(new SingleSignOutHttpSessionListener()); listener.setOrder(1); return listener; } /** * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean logOutFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); LogoutFilter logoutFilter = new LogoutFilter(autoConfig.getCasServerUrlPrefix() + "/logout?service=" + autoConfig.getServerName(), new SecurityContextLogoutHandler()); filterRegistration.setFilter(logoutFilter); filterRegistration.setEnabled(casEnabled); if (autoConfig.getSignOutFilters().size() > 0) filterRegistration.setUrlPatterns(autoConfig.getSignOutFilters()); else filterRegistration.addUrlPatterns("/logout"); filterRegistration.addInitParameter("casServerUrlPrefix", autoConfig.getCasServerUrlPrefix()); filterRegistration.addInitParameter("serverName", autoConfig.getServerName()); filterRegistration.setOrder(2); return filterRegistration; } /** * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean singleSignOutFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new SingleSignOutFilter()); filterRegistration.setEnabled(casEnabled); if (autoConfig.getSignOutFilters().size() > 0) filterRegistration.setUrlPatterns(autoConfig.getSignOutFilters()); else filterRegistration.addUrlPatterns("/*"); filterRegistration.addInitParameter("casServerUrlPrefix", autoConfig.getCasServerUrlPrefix()); filterRegistration.addInitParameter("serverName", autoConfig.getServerName()); filterRegistration.setOrder(3); return filterRegistration; } /** * 该过滤器负责用户的认证工作 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean authenticationFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new AuthenticationFilter()); filterRegistration.setEnabled(casEnabled); if (autoConfig.getAuthFilters().size() > 0) filterRegistration.setUrlPatterns(autoConfig.getAuthFilters()); else filterRegistration.addUrlPatterns("/*"); // casServerLoginUrl:cas服务的登陆url filterRegistration.addInitParameter("casServerLoginUrl", autoConfig.getCasServerLoginUrl()); // 本项目登录ip+port filterRegistration.addInitParameter("serverName", autoConfig.getServerName()); filterRegistration.addInitParameter("useSession", autoConfig.isUseSession() ? "true" : "false"); filterRegistration.addInitParameter("redirectAfterValidation", autoConfig.isRedirectAfterValidation() ? "true" : "false"); filterRegistration.setOrder(4); return filterRegistration; } /** * 该过滤器负责对Ticket的校验工作 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); Cas20ProxyReceivingTicketValidationFilter cas20ProxyReceivingTicketValidationFilter = new Cas20ProxyReceivingTicketValidationFilter(); cas20ProxyReceivingTicketValidationFilter.setServerName(autoConfig.getServerName()); filterRegistration.setFilter(cas20ProxyReceivingTicketValidationFilter); filterRegistration.setEnabled(casEnabled); if (autoConfig.getValidateFilters().size() > 0) filterRegistration.setUrlPatterns(autoConfig.getValidateFilters()); else filterRegistration.addUrlPatterns("/*"); filterRegistration.addInitParameter("casServerUrlPrefix", autoConfig.getCasServerUrlPrefix()); filterRegistration.addInitParameter("serverName", autoConfig.getServerName()); filterRegistration.setOrder(5); return filterRegistration; } /** * 该过滤器对HttpServletRequest请求包装, * 可通过HttpServletRequest的getRemoteUser()方法获得登录用户的登录名 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean httpServletRequestWrapperFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new HttpServletRequestWrapperFilter()); filterRegistration.setEnabled(true); if (autoConfig.getRequestWrapperFilters().size() > 0) filterRegistration.setUrlPatterns(autoConfig.getRequestWrapperFilters()); else filterRegistration.addUrlPatterns("/login"); filterRegistration.setOrder(6); return filterRegistration; } /** * 该过滤器使得可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 * 比如AssertionHolder.getAssertion().getPrincipal().getName()。 * 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public FilterRegistrationBean assertionThreadLocalFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new AssertionThreadLocalFilter()); filterRegistration.setEnabled(true); if (autoConfig.getAssertionFilters().size() > 0) filterRegistration.setUrlPatterns(autoConfig.getAssertionFilters()); else filterRegistration.addUrlPatterns("/*"); filterRegistration.setOrder(7); return filterRegistration; } }
启动项目进行测试即可。