前言
我们在学习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
网友评论