此文章仅仅说明在springboot整合shiro时的一些坑,并不是教程
增加依赖
<!-- 集成shiro依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0-RC2</version>
</dependency>
配置三个必须的Bean
- Realm
用于授权和登录
@Bean
public Realm realm() {
//创建自己的Realm实例
return new UserRealm();
}
- ShiroFilterChainDefinition
用于实现权限
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
// 三种方式实现定义权限路径
// 第一种:使用角色名定义
chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");
// 第二种:使用权限code定义
chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");
// 第三种:使用接口的自定义配置(此处配置之后需要在对应的接口使用@RequiresPermissions(""))
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
- CacheManager
缓存管理
@Bean
protected CacheManager cacheManager() {
return new MemoryConstrainedCacheManager();
}
还有一些配置,可以在配置文件中配置,具体配置项见 shiro配置
以下内容是为了实现前后端分离,配置shiro拦截器实现返回401状态码的需求
编写拦截器类
public class FormLoginFilter extends PathMatchingFilter {
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
Subject subject = SecurityUtils.getSubject();
boolean isAuthenticated = subject.isAuthenticated();
if (!isAuthenticated) {
HttpServletResponse resp = (HttpServletResponse) response;
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
resp.getWriter().print("NO AUTH!");
return false;
}
return true;
}
}
在之前配置的三个Bean的基础上多配置一个BeanShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置SecuritManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
//配置拦截器,实现无权限返回401,而不是跳转到登录页
filters.put("authc", new FormLoginFilter());
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
// 拦截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边
// authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
此处配置了过滤链,上面三个必须的Bean中修改其中的ShiroFilterChainDefinition
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
//不需要在此处配置权限页面,因为上面的ShiroFilterFactoryBean已经配置过,但是此处必须存在,因为shiro-spring-boot-web-starter或查找此Bean,没有会报错
return new DefaultShiroFilterChainDefinition();;
}