美文网首页Spring Boot2.0
SpringBoot整合Shiro

SpringBoot整合Shiro

作者: 蓝雄威 | 来源:发表于2018-03-20 22:30 被阅读316次

前言

我们在学习SpringBoot的时候说过,要完成某项功能,引入一些依赖,我们第一反应就是这个功能看看有没有对应的starter的依赖,因为引入了对应的starter之后可以帮我们完成自动装配的功能.

那Shiro有没有对应的starter呢?很遗憾的告诉大家,并没有!
既然没有对应的starter,那我们就必须自己去配置Shiro和SpringBoot集成相关的bean.
我们先来回顾一下在没有SpringBoot的情况下,Shiro是怎么和Spring进行集成的?

Spring整合Shiro步骤

  • (1) 需要在pom.xml添加shiro相关的依赖包.
<!--Shiro核心依赖-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.2.2</version>
</dependency>
<!--Shiro中Web相关的支持-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>1.2.2</version>
</dependency>
<!--Shiro与Spring整合-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.2.2</version>
</dependency>
  • (2) 在web.xml中配置ShiroFilter过滤器,拦截用户的请求.
<!-- shiro过虑器,DelegatingFilterProx会从spring容器中找shiroFilter -->
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • (3) 创建applicationContext-shiro.xml关于Shiro和Spring整合的配置文件,需要配置如下信息:
  • 自定义Realm
  • 安全管理器SecurityManager
  • 处理请求的ShiroFilterFactoryBean

配置如下:

<!-- 自定义Realm -->
<bean id="userRealm" class="cn.wolfcode.wms.realm.UserRealm"/>
<!-- 配置安全管理器SecurityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="userRealm"/>
</bean>
<!-- 定义ShiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/login"/>
    <property name="successUrl" value="/main"/>
    <property name="unauthorizedUrl" value="/WEB-INF/views/common/nopermission.ftl"/>
    <property name="filterChainDefinitions">
        <value>
            /js/**=anon
            /images/**=anon
            /style/**=anon
            /logout=logout
            /**=authc
        </value>
    </property>
</bean>
  • (4) 如果还需要使用Shiro注解完成权限控制,还需要在配置文件中添加如下配置:
<!-- 开启aop,使用CGlib基于继承的动态代理 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 开启shiro注解支持 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
</bean>

并在控制器方法上使用 @RequiresPermissions 注解,表示该方法是需要权限控制的.

@RequestMapping("/employee")
@RequiresPermissions("employee:page")
public String employeePage(){
    return "employee/list";
}

使用了Shiro注解控制权限之后,当登陆用户没有权限的时候,默认会抛出AuthorizationException 异常.我们会写一个控制器增强类,来对控制器中抛出的异常进行统一的管理.

//对所有的Controller做增强
@ControllerAdvice
public class ErrorAdvice {
    //需要捕获的异常
    @ExceptionHandler(AuthorizationException.class)
    public String handlerException(){
       //处理没有权限的时候的逻辑 (TODO)
        return "nopermission";//跳转到没有权限的页面.
    }
}

SpringBoot整合Shiro

其实SpringBoot整合Shiro也很简单,就是把以前xml中的配置bean变成通过注解来进行配置.可以自己写一个自定义的starter,把shiro相关的bean配置好,导入自定义的starter之后就自动的帮我们装配shiro相关的bean实例了.
后面我们也会给同学们讲如何自定义自己的starter.

接下来我们就创建一个ShiroConfig的类,把需要的bean通过注解的方式配置到ShiroConfig中.

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)//等价    <aop:config proxy-target-class="true"/>
public class ShiroConfig {
    /*
    等价于以前在web.xml中配置的filter
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new DelegatingFilterProxy("shiroFilter"));
        filterRegistrationBean.addInitParameter("targetFilterLifecycle","true");
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
    /*
    自定义Realm
     */
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
    /*
    创建安全管理器对象,关联自定义Realm
     */
    @Bean
    public DefaultWebSecurityManager securityManager(UserRealm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        return securityManager;
    }
    /*
    创建ShiroFilter对象,设置相关的属性
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        shiroFilter.setLoginUrl("/login");
        shiroFilter.setSuccessUrl("/main");
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        filterChainDefinitionMap.put("/favicon","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/html/**","anon");
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/**","authc");
        shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilter;
    }
    /*
    开启Shiro注解支持,等价与以前web.xml中的配置
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

关于SpringBoot整合Shiro的简易代码我上传到gitHub了,有需要的同学可以自行下载.
https://github.com/javalanxiongwei/springboot-shiro

相关文章

网友评论

    本文标题:SpringBoot整合Shiro

    本文链接:https://www.haomeiwen.com/subject/kfeiqftx.html