Apache Shiro和Spring boot的結合使用

實際上在Spring boot裏用Spring Security最合適,畢竟是自家東西,最重要的一點是Spring Security裏自帶有csrf filter,防止csrf攻擊,shiro裏就沒有。

但是Spring Security有點太複雜,custmize起來比較費力,不如shiro來的簡單。

如果想要在Spring boot裏使用shiro,需要進行以下配置,首先pom.xml裏要添加shiro的依賴。

 

		<dependency>
		    <groupId>org.apache.shiro</groupId>
		    <artifactId>shiro-spring</artifactId>
		    <version>1.2.5</version>
		</dependency>
		<dependency>
		    <groupId>org.apache.shiro</groupId>
		    <artifactId>shiro-ehcache</artifactId>
		    <version>1.2.5</version>
		</dependency>
		<dependency>
		    <groupId>com.github.theborakompanioni</groupId>
		    <artifactId>thymeleaf-extras-shiro</artifactId>
		    <version>1.2.1</version>
		</dependency>

 shiro官方只提供了jsp的標籤,沒有提供thymeleaf的,而thymeleaf在spring boot裏應用已經很廣泛了,這裏依賴了一個第三方包。

 

然後就是shiro的配置文件,這裏我們使用java-based 配置

 

@Configuration
public class ShiroConfiguration {
	
	@Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
	
	@Bean(name = "hashedCredentialsMatcher")
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
		credentialsMatcher.setHashAlgorithmName("MD5");
		credentialsMatcher.setHashIterations(2);
		credentialsMatcher.setStoredCredentialsHexEncoded(true);
		return credentialsMatcher;
	}
	
	@Bean(name = "shiroRealm")
	@DependsOn("lifecycleBeanPostProcessor")
    public ShiroRealm shiroRealm() {
		ShiroRealm realm = new ShiroRealm(); 
		realm.setCredentialsMatcher(hashedCredentialsMatcher());
        return realm;
    }
	
	@Bean(name = "ehCacheManager")
	@DependsOn("lifecycleBeanPostProcessor")
	public EhCacheManager ehCacheManager(){
		EhCacheManager ehCacheManager = new EhCacheManager();
		return ehCacheManager;
	}
	
	@Bean(name = "securityManager")
	public SecurityManager securityManager(){
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(shiroRealm());
		securityManager.setCacheManager(ehCacheManager());
		return securityManager;
	}

	@Bean(name = "shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(){
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager());
		
		Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
		LogoutFilter logoutFilter = new LogoutFilter();
		logoutFilter.setRedirectUrl("/login");
		filters.put("logout", logoutFilter);
		shiroFilterFactoryBean.setFilters(filters);
		
		Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
		filterChainDefinitionManager.put("/logout", "logout");
		filterChainDefinitionManager.put("/user/**", "authc,roles[user]");
		filterChainDefinitionManager.put("/shop/**", "authc,roles[shop]");
		filterChainDefinitionManager.put("/admin/**", "authc,roles[admin]");
		filterChainDefinitionManager.put("/**", "anon");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
		
		shiroFilterFactoryBean.setLoginUrl("/login");
		shiroFilterFactoryBean.setSuccessUrl("/");
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		
		return shiroFilterFactoryBean;
	}

	@Bean
	@ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }
	
	@Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(securityManager());
        return aasa;
    }
	
	@Bean(name = "shiroDialect")
	public ShiroDialect shiroDialect(){
		return new ShiroDialect();
	}
}

 

  1.  LifecycleBeanPostProcessor,這是個DestructionAwareBeanPostProcessor的子類,負責org.apache.shiro.util.Initializable類型bean的生命週期的,初始化和銷燬。主要是AuthorizingRealm類的子類,以及EhCacheManager類。
  2. HashedCredentialsMatcher,這個類是爲了對密碼進行編碼的,防止密碼在數據庫裏明碼保存,當然在登陸認證的生活,這個類也負責對form裏輸入的密碼進行編碼。
  3. ShiroRealm,這是個自定義的認證類,繼承自AuthorizingRealm,負責用戶的認證和權限的處理,可以參考JdbcRealm的實現。
  4. EhCacheManager,緩存管理,用戶登陸成功後,把用戶信息和權限信息緩存起來,然後每次用戶請求時,放入用戶的session中,如果不設置這個bean,每個請求都會查詢一次數據庫。
  5. SecurityManager,權限管理,這個類組合了登陸,登出,權限,session的處理,是個比較重要的類。
  6. ShiroFilterFactoryBean,是個factorybean,爲了生成ShiroFilter。它主要保持了三項數據,securityManager,filters,filterChainDefinitionManager。
  7. DefaultAdvisorAutoProxyCreator,Spring的一個bean,由Advisor決定對哪些類的方法進行AOP代理。
  8. AuthorizationAttributeSourceAdvisor,shiro裏實現的Advisor類,內部使用AopAllianceAnnotationsAuthorizingMethodInterceptor來攔截用以下註解的方法。老實說,這裏注入securityManager,我不知道有啥用,從source上看不出它在什麼地方會被調用。
    private static final Class<? extends Annotation>[] AUTHZ_ANNOTATION_CLASSES =
            new Class[] {
                    RequiresPermissions.class, RequiresRoles.class,
                    RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class
            };

 9.ShiroDialect,爲了在thymeleaf裏使用shiro的標籤的bean

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章