本文最新springboor版本Springboot2.0.0-SNAPSHOTjava
本文分爲兩部門,以「華麗的分割線」分開,第一部分主要講傳統或者稱舊版的shiro+cas,第二部門講新版的shiro+cas,藉助buji-pac4j。git
若是你想在Springboot中使用shiro+cas,請認真閱讀本文,爲你提供最直接的介紹。注意本文不提供shiro或者cas的源碼分析或原理介紹。只描述springboot+shiro+cas。github
1. Springboot在activemq模塊中添加了shiro的功能。Springboot在springsecurity模塊中添加了cas的功能。Springboot只提供了對shiro和cas的單獨支持。Springboot未提供shiro+cas的共同支持。web
2. 若是想要使用Springboot+shiro+cas,可參考基本的Spring+shiro+cas功能,具體以下:spring
(1) 在pom中添加shiro依賴。apache
可以使用Springboot支持的shiro功能,由於在其中有進一步依賴shiro功能,即springboot
<dependency>源碼分析
<groupId>org.apache.activemq</groupId>.net
<artifactId>activemq-shiro</artifactId> <!-- springboot默認支持版本,因此不須要版本信息 -->server
</dependency>
也但是使用基本的shiro依賴,即
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.4</version> <!-- 注意版本要參考官方提供的支持版本 -->
</dependency>
(2) 在pom中添加shiro-cas依賴。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>1.2.4</version> <!-- 注意與(1)中shiro版本保持一致 -->
</dependency>
(3) configuration文件。原文總體粘貼以下,不作詳細分析:
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by willwu on 16-4-14.
*/
@Configuration
public class ShiroCasConfiguration {
private static final String casFilterUrlPattern = "/shiro-cas";
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
filterRegistration.addInitParameter("targetFilterLifecycle", "true");
filterRegistration.setEnabled(true);
filterRegistration.addUrlPatterns("/*");
return filterRegistration;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Value("${shiro.cas}") String casServerUrlPrefix,
@Value("${shiro.server}") String shiroServerUrlPrefix) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
CasRealm casRealm = new CasRealm();
casRealm.setDefaultRoles("ROLE_USER");
casRealm.setCasServerUrlPrefix(casServerUrlPrefix);
casRealm.setCasService(shiroServerUrlPrefix + casFilterUrlPattern);
securityManager.setRealm(casRealm);
securityManager.setCacheManager(new MemoryConstrainedCacheManager());
securityManager.setSubjectFactory(new CasSubjectFactory());
return securityManager;
}
private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) {
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put(casFilterUrlPattern, "casFilter");
filterChainDefinitionMap.put("/logout","logout");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
}
/**
* CAS Filter
*/
@Bean(name = "casFilter")
public CasFilter getCasFilter(@Value("${shiro.cas}") String casServerUrlPrefix,
@Value("${shiro.server}") String shiroServerUrlPrefix) {
CasFilter casFilter = new CasFilter();
casFilter.setName("casFilter");
casFilter.setEnabled(true);
String loginUrl = casServerUrlPrefix + "/login?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
casFilter.setFailureUrl(loginUrl);
return casFilter;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager,
CasFilter casFilter,
@Value("${shiro.cas}") String casServerUrlPrefix,
@Value("${shiro.server}") String shiroServerUrlPrefix) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
String loginUrl = casServerUrlPrefix + "/login?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
shiroFilterFactoryBean.setLoginUrl(loginUrl);
shiroFilterFactoryBean.setSuccessUrl("/");
Map<String, Filter> filters = new HashMap<>();
filters.put("casFilter", casFilter);
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl(casServerUrlPrefix + "/logout?service=" + shiroServerUrlPrefix);
filters.put("logout",logoutFilter);
shiroFilterFactoryBean.setFilters(filters);
loadShiroFilterChain(shiroFilterFactoryBean);
return shiroFilterFactoryBean;
}
}
補充說明: 有了以上(1)(2)的pom依賴和(3)的配置,就可以使用springboot+shiro+cas。(3)中代碼來源gihub地址: https://github.com/willwu1984/springboot-cas-shiro。在Springboot2.0.0-SHAPSHOT下親測可行。
///****************************************華麗的分割線*******************************************///
第二部分暫時還沒徹底理解。