一、权限认证

将ShiroConfig中的权限map改为从数据库中获取的权限

  1. //配置请求的URL与过滤器的关系
  2. Map<String, String> map = new LinkedHashMap<>();
  3. map.put("/manager/login", "anon");
  4. map.put("/menu/get","jwt");
  5. shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

由于在配置类中注入UserMapper的话,不会生效,因为@Configuration注入时,UserMapper还未注入,所以我们单独写一个类来用于封装权限map

1.1 MyPermissionsAuthorizationFilter自定义过滤器

不自定义的话拦截下来无法获取有效信息

  1. import com.fasterxml.jackson.databind.ObjectMapper;
  2. import com.woniuxy.ticket.commons.entity.ResponseResult;
  3. import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
  4. import javax.servlet.ServletRequest;
  5. import javax.servlet.ServletResponse;
  6. import java.io.IOException;
  7. public class MyPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {
  8. @Override
  9. protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
  10. ResponseResult<Void> result = new ResponseResult<>(403, "没有权限");
  11. ObjectMapper objectMapper = new ObjectMapper();
  12. response.getWriter().write(objectMapper.writeValueAsString(result));
  13. return false;
  14. }
  15. }

1.2 PermMapFactoryBean

  1. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  2. import com.woniuxy.ticket.auth.entity.Perms;
  3. import com.woniuxy.ticket.auth.mapper.PermsMapper;
  4. import org.springframework.beans.factory.FactoryBean;
  5. import javax.annotation.Resource;
  6. import java.util.LinkedHashMap;
  7. import java.util.Map;
  8. public class PermMapFactoryBean implements FactoryBean<Map<String, String>> {
  9. @Resource
  10. private PermsMapper permsMapper;
  11. @Override
  12. public Map<String, String> getObject() {
  13. //配置请求的URL与过滤器的关系
  14. Map<String, String> map = new LinkedHashMap<>();
  15. map.put("/manager/login", "anon");
  16. map.put("/menu/get", "jwt");
  17. QueryWrapper<Perms> queryWrapper = new QueryWrapper<>();
  18. queryWrapper.eq("type", "a");
  19. queryWrapper.eq("status", "y");
  20. permsMapper.selectList(queryWrapper).forEach(p -> {
  21. map.put(p.getLink(), "jwt,perms[" + p.getCode() + "]");
  22. });
  23. return map;
  24. }
  25. @Override
  26. public Class<?> getObjectType() {
  27. return Map.class;
  28. }
  29. }

1.3 ShiroConfig修改

  1. @Bean
  2. public MyPermissionsAuthorizationFilter myPermissionsAuthorizationFilter() {
  3. return new MyPermissionsAuthorizationFilter();
  4. }
  5. @Bean
  6. public PermMapFactoryBean permMapFactoryBean() {
  7. return new PermMapFactoryBean();
  8. }
  9. @Bean
  10. public ShiroFilterFactoryBean shiroFilterFactoryBean() {
  11. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  12. shiroFilterFactoryBean.setSecurityManager(securityManager());
  13. //增加自定义的过滤器
  14. Map<String, Filter> filterMap = new HashMap<>();
  15. filterMap.put("jwt", jwtFilter());
  16. filterMap.put("perms", myPermissionsAuthorizationFilter());
  17. shiroFilterFactoryBean.setFilters(filterMap);
  18. shiroFilterFactoryBean.setFilterChainDefinitionMap(permMapFactoryBean().getObject());
  19. return shiroFilterFactoryBean;
  20. }

1.4 DbRealm

  1. @Resource
  2. private UserMapper userMapper;
  3. @Resource
  4. private Audience audience;
  5. /**
  6. * 授权,获取用户的权限列表
  7. */
  8. @Override
  9. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  10. String jwt = principals.getPrimaryPrincipal().toString();
  11. int id = JwtUtil.getUserId(jwt, audience.getBase64Secret());
  12. SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
  13. List<Perms> perms = userMapper.findUserPerms(id).getRolePermsDto().getPerms();
  14. perms.forEach(p ->{
  15. info.addStringPermission(p.getCode());
  16. System.out.println(p.getCode());
  17. });
  18. return info;
  19. }

二、测试

2.1 添加测试请求Controller

PermController

  1. @RestController
  2. @RequestMapping("/perm")
  3. public class PermController {
  4. @GetMapping("/list")
  5. public ResponseResult list(){
  6. return new ResponseResult(200,"可以访问/perm/list方法");
  7. }
  8. }

2.2 获取JWT

先登录,获取一段JWT
image.png

2.3 打断点,进行调试

image.png

2.4 利用POSTMAN测试

注意是将JWT放入header中发出请求

2.4.1 有权限用户

image.png
image.png
可见从JWT中获取了数据,去数据库中查询权限,查询到有权限
访问请求方法获取数据
image.png

2.4.2 无权限用户

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