一、权限认证
将ShiroConfig中的权限map改为从数据库中获取的权限
//配置请求的URL与过滤器的关系Map<String, String> map = new LinkedHashMap<>();map.put("/manager/login", "anon");map.put("/menu/get","jwt");shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
由于在配置类中注入UserMapper的话,不会生效,因为@Configuration注入时,UserMapper还未注入,所以我们单独写一个类来用于封装权限map
1.1 MyPermissionsAuthorizationFilter自定义过滤器
不自定义的话拦截下来无法获取有效信息
import com.fasterxml.jackson.databind.ObjectMapper;import com.woniuxy.ticket.commons.entity.ResponseResult;import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import java.io.IOException;public class MyPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {ResponseResult<Void> result = new ResponseResult<>(403, "没有权限");ObjectMapper objectMapper = new ObjectMapper();response.getWriter().write(objectMapper.writeValueAsString(result));return false;}}
1.2 PermMapFactoryBean
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.woniuxy.ticket.auth.entity.Perms;import com.woniuxy.ticket.auth.mapper.PermsMapper;import org.springframework.beans.factory.FactoryBean;import javax.annotation.Resource;import java.util.LinkedHashMap;import java.util.Map;public class PermMapFactoryBean implements FactoryBean<Map<String, String>> {@Resourceprivate PermsMapper permsMapper;@Overridepublic Map<String, String> getObject() {//配置请求的URL与过滤器的关系Map<String, String> map = new LinkedHashMap<>();map.put("/manager/login", "anon");map.put("/menu/get", "jwt");QueryWrapper<Perms> queryWrapper = new QueryWrapper<>();queryWrapper.eq("type", "a");queryWrapper.eq("status", "y");permsMapper.selectList(queryWrapper).forEach(p -> {map.put(p.getLink(), "jwt,perms[" + p.getCode() + "]");});return map;}@Overridepublic Class<?> getObjectType() {return Map.class;}}
1.3 ShiroConfig修改
@Beanpublic MyPermissionsAuthorizationFilter myPermissionsAuthorizationFilter() {return new MyPermissionsAuthorizationFilter();}@Beanpublic PermMapFactoryBean permMapFactoryBean() {return new PermMapFactoryBean();}@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean() {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager());//增加自定义的过滤器Map<String, Filter> filterMap = new HashMap<>();filterMap.put("jwt", jwtFilter());filterMap.put("perms", myPermissionsAuthorizationFilter());shiroFilterFactoryBean.setFilters(filterMap);shiroFilterFactoryBean.setFilterChainDefinitionMap(permMapFactoryBean().getObject());return shiroFilterFactoryBean;}
1.4 DbRealm
@Resourceprivate UserMapper userMapper;@Resourceprivate Audience audience;/*** 授权,获取用户的权限列表*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String jwt = principals.getPrimaryPrincipal().toString();int id = JwtUtil.getUserId(jwt, audience.getBase64Secret());SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();List<Perms> perms = userMapper.findUserPerms(id).getRolePermsDto().getPerms();perms.forEach(p ->{info.addStringPermission(p.getCode());System.out.println(p.getCode());});return info;}
二、测试
2.1 添加测试请求Controller
PermController
@RestController@RequestMapping("/perm")public class PermController {@GetMapping("/list")public ResponseResult list(){return new ResponseResult(200,"可以访问/perm/list方法");}}
2.2 获取JWT
2.3 打断点,进行调试
2.4 利用POSTMAN测试
2.4.1 有权限用户


可见从JWT中获取了数据,去数据库中查询权限,查询到有权限
访问请求方法获取数据
2.4.2 无权限用户


在JWT中得到数据后,去数据库中查询发现并无权限
返回MyPermissionsAuthorizationFilter自定义拦截器中信息
