Springboot學習筆記之springboot+shiro+cas

本文最新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下親測可行。

 

///****************************************華麗的分割線*******************************************///

第二部分暫時還沒徹底理解。

相關文章
相關標籤/搜索