服務部署:
環境准備:
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; } }
啟動項目進行測試即可。