我们开发时候有时候要把传统spring shiro转成spring boot项目,或者直接集成,name我们要搞清楚一个知识,就是 xml配置和spring bean代码配置的关系,这一点很重要,因为spring boot是没有xml配置文件的(也不绝对,spring boot也是可以引用xml配置的)

引入依赖:

   <dependency>
      <artifactId>ehcache-core</artifactId>
      <groupId>net.sf.ehcache</groupId>
      <version>2.5.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.2.2</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
   <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.2.3</version>
    </dependency>

如果你出现错误 找不到slf4j,引入依赖

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

传统xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx.xsd">

  <context:component-scan base-package="com.len"/>
  <!--定义realm-->
  <bean id="myRealm" class="com.len.core.shiro.LoginRealm">
    <property name="credentialsMatcher" ref="credentialsMatcher"/>
  </bean>
  <bean id="permissionFilter" class="com.len.core.filter.PermissionFilter"/>
  <!--目前去掉自定义拦截验证 由个人处理登录业务-->
  <!--<bean id="customAdvicFilter" class="com.len.core.filter.CustomAdvicFilter">
    <property name="failureKeyAttribute" value="shiroLoginFailure"/>
  </bean>-->
  <bean id="verfityCodeFilter" class="com.len.core.filter.VerfityCodeFilter">
    <property name="failureKeyAttribute" value="shiroLoginFailure"/>
    <property name="jcaptchaParam" value="code"/>
    <property name="verfitiCode" value="true"/>
  </bean>
  <!-- Shiro过滤器 -->
  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
  <property name="loginUrl" value="/login"/>
    <property name="unauthorizedUrl" value="/goLogin" />
    <property name="filters">
      <map>
        <entry key="per" value-ref="permissionFilter"/>
        <entry key="verCode" value-ref="verfityCodeFilter"/>
        <!--<entry key="main" value-ref="customAdvicFilter"/>-->
      </map>
    </property>
    <property name="filterChainDefinitions">
      <value>
        <!-- /** = anon所有url都可以匿名访问 -->
       /login = verCode,anon
       /getCode = anon
        /logout = logout
        /plugin/** = anon
        <!-- /** = authc 所有url都必须认证通过才可以访问-->
        /user/**=per
       <!-- /login = main-->
        /** = authc
      </value>
    </property>
  </bean>

  <!--安全管理器-->
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
    <property name="cacheManager" ref="cacheManager" />
    <!--<property name="rememberMeManager" ref="rememberMeManager" />-->
  </bean>

  <!-- 凭证匹配器 -->
  <bean id="credentialsMatcher"
    class="com.len.core.shiro.RetryLimitCredentialsMatcher">
    <constructor-arg index="0" ref="cacheManager"/>
    <constructor-arg index="1" value="5"/>
    <property name="hashAlgorithmName" value="md5"/>
    <property name="hashIterations" value="4"/>
  </bean>
  <!--缓存-->
  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:ehcache/ehcache.xml"/>
  </bean>


  <!--开启注解-->
  <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
  </bean>

  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

</beans>

转换成bean 新建类ShiroConfig

@Configuration
public class ShiroConfig {


  @Bean
  public RetryLimitCredentialsMatcher getRetryLimitCredentialsMatcher(){
    RetryLimitCredentialsMatcher rm=new RetryLimitCredentialsMatcher(getCacheManager(),"5");
    rm.setHashAlgorithmName("md5");
    rm.setHashIterations(4);
    return rm;

  }
  @Bean
  public LoginRealm getLoginRealm(){
    LoginRealm realm= new LoginRealm();
    realm.setCredentialsMatcher(getRetryLimitCredentialsMatcher());
    return realm;
  }

  @Bean
  public EhCacheManager getCacheManager(){
    EhCacheManager ehCacheManager=new EhCacheManager();
    ehCacheManager.setCacheManagerConfigFile("classpath:ehcache/ehcache.xml");
    return ehCacheManager;
  }

  @Bean
  public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }

  @Bean(name="securityManager")
  public DefaultWebSecurityManager getDefaultWebSecurityManager(){
    DefaultWebSecurityManager dwm=new DefaultWebSecurityManager();
    dwm.setRealm(getLoginRealm());
    dwm.setCacheManager(getCacheManager());
    return dwm;
  }

  @Bean
  public PermissionFilter getPermissionFilter(){
    PermissionFilter pf=new PermissionFilter();
    return pf;
  }

  @Bean
  public VerfityCodeFilter getVerfityCodeFilter(){
    VerfityCodeFilter vf= new VerfityCodeFilter();
    vf.setFailureKeyAttribute("shiroLoginFailure");
    vf.setJcaptchaParam("code");
    vf.setVerfitiCode(true);
    return vf;
  }

  @Bean(name = "shiroFilter")
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
    ShiroFilterFactoryBean sfb = new ShiroFilterFactoryBean();
    sfb.setSecurityManager(getDefaultWebSecurityManager());
    sfb.setLoginUrl("/login");
    sfb.setUnauthorizedUrl("/goLogin");
    Map<String, Filter> filters=new HashMap<>();
    filters.put("per",getPermissionFilter());
    filters.put("verCode",getVerfityCodeFilter());
    sfb.setFilters(filters);

    Map<String, String> filterMap = new LinkedHashMap<>();
    filterMap.put("/login","verCode,anon");
    //filterMap.put("/login","anon");
    filterMap.put("/getCode","anon");
    filterMap.put("/logout","logout");
    filterMap.put("/plugin/**","anon");
    filterMap.put("/user/**","per");
    filterMap.put("/**","authc");
    sfb.setFilterChainDefinitionMap(filterMap);
    return sfb;
  }

  @Bean
  public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    advisorAutoProxyCreator.setProxyTargetClass(true);
    return advisorAutoProxyCreator;
  }

  @Bean
  public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(){
    AuthorizationAttributeSourceAdvisor as=new AuthorizationAttributeSourceAdvisor();
    as.setSecurityManager(getDefaultWebSecurityManager());
    return as;
  }

  @Bean
  public FilterRegistrationBean delegatingFilterProxy(){
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    DelegatingFilterProxy proxy = new DelegatingFilterProxy();
    proxy.setTargetFilterLifecycle(true);
    proxy.setTargetBeanName("shiroFilter");
    filterRegistrationBean.setFilter(proxy);
    return filterRegistrationBean;
  }

其中有个别类是自定义的拦截器和 realm,此时spring 即能注入shiro 也就是 spring boot集成上了 shiro

如果你因为其他配置引起一些失败,可以参考开源项目 lenos快速开发脚手架 spring boot版本,其中有对shiro的集成,可以用来学习

地址:https://gitee.com/bweird/lenosp

演示地址:www.lenosp.cn

05-18 03:40