一、权限认证
将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 {
@Override
protected 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>> {
@Resource
private PermsMapper permsMapper;
@Override
public 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;
}
@Override
public Class<?> getObjectType() {
return Map.class;
}
}
1.3 ShiroConfig修改
@Bean
public MyPermissionsAuthorizationFilter myPermissionsAuthorizationFilter() {
return new MyPermissionsAuthorizationFilter();
}
@Bean
public PermMapFactoryBean permMapFactoryBean() {
return new PermMapFactoryBean();
}
@Bean
public 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
@Resource
private UserMapper userMapper;
@Resource
private Audience audience;
/**
* 授权,获取用户的权限列表
*/
@Override
protected 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自定义拦截器中信息