Spring boot 与 Shiro的整合
Shiro核心API
Subject:用户主体(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm)
Realm:shrio连接数据的桥梁
github地址(基础的springboot与shiro的整合demo,不喜勿喷,欢迎star,后续更新springboot+shiro+jwt实现前后端分离demo)
springboot-shiro-v1 (重要的事情说三遍欢迎star欢迎star欢迎star,找工作用的,谢谢支持啦!)
整合Shiro
添加Pom.xml配置信息
<!-- shiro 权限控制 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<!-- shiro 权限控制 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- shiro ehcache (shiro缓存)-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 通用 mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.1.7</version>
</dependency>
<!-- commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--支持使用 JDBC 访问数据库-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--添加适用于生产环境的功能,如性能指标和监测等功能。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--Mysql / DataSource-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<!--Json Support-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.43</version>
</dependency>
</dependencies>
自定义Realm类
/**
* @author: xipiker
* @Date: 2019-8-3
* @Description: UserRealm
*/
public class UserRealm extends AuthorizingRealm {
@Autowired
private springShiroUserService springShiroUserService;
private Logger log = LoggerFactory.getLogger(this.getClass());
/**
* 执行授权逻辑
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("执行授权逻辑");
//给资源进行授权
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//添加授权字符串
//info.addStringPermission("user:add");
Subject subject = SecurityUtils.getSubject();
springShiroUser user = (springShiroUser) subject.getPrincipal();
springShiroUser user2 = springShiroUserService.findById(user.getId());
info.addStringPermission(user2.getPerms());
return info;
}
/**
* 执行认证逻辑
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.printf("执行认证逻辑");
//假设数据库的用户名和密码
// String username = "xipiker";
// String password = "123456";
//编写shiro判断逻辑,判断用户名密码
//1.判断用户名
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
springShiroUser springShiroUser = springShiroUserService.findByName(usernamePasswordToken.getUsername());
if(springShiroUser == null){
//用户名不存在
return null;
}
//2.判断密码
return new SimpleAuthenticationInfo(springShiroUser, springShiroUser.getPassword(), "");
}
}
ShiroConfig配置信息相关业务逻辑
/**
* @author: xipiker
* @Date: 2019-8-3
* @Description: ShiroConfig
*/
@Configuration
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
/**
* Shiro内置过滤器,可以实现权限相关的拦截器
* 常用过滤器:
* anon:无需认证(登录)可以访问
* authc:必须认证才可以访问
* user:如果使用rememberMe的功能可以直接访问
* perms:该资源必须得到资源权限才可以访问
* role:该资源必须得到角色权限才可以访问
*/
Map<String, String> filterMap = new LinkedHashMap<String, String>();
// filterMap.put("/add", "authc");
// filterMap.put("/update", "authc");
filterMap.put("/test", "anon");
//放行login.html
filterMap.put("/login", "anon");
//授权过滤器
//注意:当授权拦截后,shiro会自动跳转到未授权页面
filterMap.put("/add", "perms[user:add]");
filterMap.put("/update", "perms[user:update]");
filterMap.put("/*", "authc");
//拦截成功会默认跳转到login.jsp
//修改默认拦截成功跳转到login.jsp页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
//设置未授权拦截器
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManager
*/
@Bean(name="securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联Realm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 创建Realm
*/
@Bean(name="userRealm")
public UserRealm getRealm(){
return new UserRealm();
}
}
数据库表结构
数据表的基本结构图
实现效果
说明:/test为无需权限所有人都可以访问
说明:/add为权限配置为[user:add]的用户才可以访问
说明:/update为权限配置为[user:update]的用户才可以访问
说明:/toLogin为登录页面
登录用户1,username:xipiker password:123456 拥有权限:[user:add],可以访问/add,但是无权访问/update
登录用户2,username:admin password:admin 拥有权限:[user:update],可以访问/update,但是无权访问/add