先描述一个业务场景,有新增,修改,删除 三个功能
用户名:zhang 的用户 角色为管理员,拥有所有权限
用户名:zhang123 的用户角色为普通用户,只有新增的权限
3.1 创建TestController
@RestController @RequestMapping("/test") public class TestController { @Autowired private UserService userService; @RequiresPermissions("system:user:add") @RequestMapping("/add") public String add(User loginUser,ServletRequest request){ return "add"; } @RequiresRoles("admin") @RequestMapping("/modify") public String modify(User loginUser,ServletRequest request){ return "modify"; } @RequiresPermissions("system:user:delete") @RequestMapping("/delete") public String delete(User loginUser,ServletRequest request){ return "delete"; } }
1. @RequiresPermissions("system:user:add") 代表用户有新增的权限才可以访问 相当于 subject.checkPermitted("system:user:add")
2. @RequiresRoles("admin") 代表用户角色为admin才可以访问 相当于 subject.checkRole("admin")
使用注解需要开启Spring AOP否则不生效
//自动代理所有的advisor @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager()); return advisor; }
3.2 创建两个接口 findRoles,findPermissions 主要用于查询用户所属的角色/权限
@Override public Set<String> findRoles(String username) { return userDao.findRoles(username); } @Override public Set<String> findPermissions(String username) { return userDao.findPermissions(username); }
3.3 Realm 授权
/** * 授权 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //在数据库中查询用户拥有的角色/权限 authorizationInfo.setRoles(userService.findRoles(username)); authorizationInfo.setStringPermissions(userService.findPermissions(username)); return authorizationInfo; }
在数据库中添加一些测试数据
用户(sys_users)
角色(sys_roles)
权限(sys_permissions)
用户角色关系(sys_users_roles)
角色权限关系(sys_roles_permissions)
3.4 创建全局异常处理(在ShiroConfig中)
/** * 注册全局异常处理 * @return */ @Bean(name = "exceptionHandler") public HandlerExceptionResolver handlerExceptionResolver() { return new ExceptionHandler(); }
public class ExceptionHandler implements HandlerExceptionResolver{ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView mv = new ModelAndView(); FastJsonJsonView view = new FastJsonJsonView(); Map<String,Object> attributes = new HashMap<>(); if (ex instanceof UnauthorizedException) { attributes.put("code", "1000001"); attributes.put("msg", "用户无权限"); }else if(ex instanceof UnknownAccountException){ attributes.put("code", "1000002"); attributes.put("msg", "用户名密码有误"); }else if(ex instanceof IncorrectCredentialsException){ attributes.put("code", "1000002"); attributes.put("msg", "用户名密码有误"); }else if(ex instanceof LockedAccountException){ attributes.put("code", "1000003"); attributes.put("msg", "账号已被锁定"); }else { attributes.put("code", "1000004"); attributes.put("msg", ex.getMessage()); } view.setAttributesMap(attributes); mv.setView(view); return mv; } }
启动项目测试一下,先登录用户:zhang 管理员
新增,修改,删除都可以请求
在登录用户:zhang123 普通用户
经测试,新增可以正常请求,当请求删除修改时提示无权限