shiro PermissionUtil
Posted tonggc1668
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro PermissionUtil相关的知识,希望对你有一定的参考价值。
package org.linlinjava.litemall.admin.util; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; public class Permission private RequiresPermissions requiresPermissions; private RequiresPermissionsDesc requiresPermissionsDesc; private String api; public RequiresPermissions getRequiresPermissions() return requiresPermissions; public RequiresPermissionsDesc getRequiresPermissionsDesc() return requiresPermissionsDesc; public void setRequiresPermissions(RequiresPermissions requiresPermissions) this.requiresPermissions = requiresPermissions; public void setRequiresPermissionsDesc(RequiresPermissionsDesc requiresPermissionsDesc) this.requiresPermissionsDesc = requiresPermissionsDesc; public String getApi() return api; public void setApi(String api) this.api = api;
package org.linlinjava.litemall.admin.util; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.MethodUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; import org.linlinjava.litemall.admin.vo.PermVo; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Controller; import org.springframework.util.ClassUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.lang.reflect.Method; import java.util.*; public class PermissionUtil public static List<PermVo> listPermVo(List<Permission> permissions) List<PermVo> root = new ArrayList<>(); for (Permission permission : permissions) RequiresPermissions requiresPermissions = permission.getRequiresPermissions(); RequiresPermissionsDesc requiresPermissionsDesc = permission.getRequiresPermissionsDesc(); String api = permission.getApi(); String[] menus = requiresPermissionsDesc.menu(); if (menus.length != 2) throw new RuntimeException("目前只支持两级菜单"); String menu1 = menus[0]; PermVo perm1 = null; for (PermVo permVo : root) if (permVo.getLabel().equals(menu1)) perm1 = permVo; break; if (perm1 == null) perm1 = new PermVo(); perm1.setId(menu1); perm1.setLabel(menu1); perm1.setChildren(new ArrayList<>()); root.add(perm1); String menu2 = menus[1]; PermVo perm2 = null; for (PermVo permVo : perm1.getChildren()) if (permVo.getLabel().equals(menu2)) perm2 = permVo; break; if (perm2 == null) perm2 = new PermVo(); perm2.setId(menu2); perm2.setLabel(menu2); perm2.setChildren(new ArrayList<>()); perm1.getChildren().add(perm2); String button = requiresPermissionsDesc.button(); PermVo leftPerm = null; for (PermVo permVo : perm2.getChildren()) if (permVo.getLabel().equals(button)) leftPerm = permVo; break; if (leftPerm == null) leftPerm = new PermVo(); leftPerm.setId(requiresPermissions.value()[0]); leftPerm.setLabel(requiresPermissionsDesc.button()); leftPerm.setApi(api); perm2.getChildren().add(leftPerm); else // TODO // 目前限制Controller里面每个方法的RequiresPermissionsDesc注解是唯一的 // 如果允许相同,可能会造成内部权限不一致。 throw new RuntimeException("权限已经存在,不能添加新权限"); return root; public static List<Permission> listPermission(ApplicationContext context, String basicPackage) Map<String, Object> map = context.getBeansWithAnnotation(Controller.class); List<Permission> permissions = new ArrayList<>(); for (Map.Entry<String, Object> entry : map.entrySet()) Object bean = entry.getValue(); if (!StringUtils.contains(ClassUtils.getPackageName(bean.getClass()), basicPackage)) continue; Class<?> clz = bean.getClass(); Class controllerClz = clz.getSuperclass(); RequestMapping clazzRequestMapping = AnnotationUtils.findAnnotation(controllerClz, RequestMapping.class); List<Method> methods = MethodUtils.getMethodsListWithAnnotation(controllerClz, RequiresPermissions.class); for (Method method : methods) RequiresPermissions requiresPermissions = AnnotationUtils.getAnnotation(method, RequiresPermissions.class); RequiresPermissionsDesc requiresPermissionsDesc = AnnotationUtils.getAnnotation(method, RequiresPermissionsDesc.class); if (requiresPermissions == null || requiresPermissionsDesc == null) continue; String api = ""; if (clazzRequestMapping != null) api = clazzRequestMapping.value()[0]; PostMapping postMapping = AnnotationUtils.getAnnotation(method, PostMapping.class); if (postMapping != null) api = "POST " + api + postMapping.value()[0]; Permission permission = new Permission(); permission.setRequiresPermissions(requiresPermissions); permission.setRequiresPermissionsDesc(requiresPermissionsDesc); permission.setApi(api); permissions.add(permission); continue; GetMapping getMapping = AnnotationUtils.getAnnotation(method, GetMapping.class); if (getMapping != null) api = "GET " + api + getMapping.value()[0]; Permission permission = new Permission(); permission.setRequiresPermissions(requiresPermissions); permission.setRequiresPermissionsDesc(requiresPermissionsDesc); permission.setApi(api); permissions.add(permission); continue; // TODO // 这里只支持GetMapping注解或者PostMapping注解,应该进一步提供灵活性 throw new RuntimeException("目前权限管理应该在method的前面使用GetMapping注解或者PostMapping注解"); return permissions; public static Set<String> listPermissionString(List<Permission> permissions) Set<String> permissionsString = new HashSet<>(); for (Permission permission : permissions) permissionsString.add(permission.getRequiresPermissions().value()[0]); return permissionsString;
package org.linlinjava.litemall.admin.vo; import java.util.List; public class PermVo private String id; private String label; private String api; private List<PermVo> children; public String getId() return id; public void setId(String id) this.id = id; public String getLabel() return label; public void setLabel(String label) this.label = label; public void setApi(String api) this.api = api; public String getApi() return api; public List<PermVo> getChildren() return children; public void setChildren(List<PermVo> children) this.children = children;
package org.linlinjava.litemall.admin.web; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; import org.linlinjava.litemall.admin.service.LogHelper; import org.linlinjava.litemall.core.util.RegexUtil; import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder; import org.linlinjava.litemall.core.validator.Order; import org.linlinjava.litemall.core.validator.Sort; import org.linlinjava.litemall.db.domain.LitemallAdmin; import org.linlinjava.litemall.db.service.LitemallAdminService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotNull; import java.util.List; import static org.linlinjava.litemall.admin.util.AdminResponseCode.*; @RestController @RequestMapping("/admin/admin") @Validated public class AdminAdminController private final Log logger = LogFactory.getLog(AdminAdminController.class); @Autowired private LitemallAdminService adminService; @Autowired private LogHelper logHelper; @RequiresPermissions("admin:admin:list") @RequiresPermissionsDesc(menu = "系统管理", "管理员管理", button = "查询") @GetMapping("/list") public Object list(String username, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer limit, @Sort @RequestParam(defaultValue = "add_time") String sort, @Order @RequestParam(defaultValue = "desc") String order) List<LitemallAdmin> adminList = adminService.querySelective(username, page, limit, sort, order); return ResponseUtil.okList(adminList); private Object validate(LitemallAdmin admin) String name = admin.getUsername(); if (StringUtils.isEmpty(name)) return ResponseUtil.badArgument(); if (!RegexUtil.isUsername(name)) return ResponseUtil.fail(ADMIN_INVALID_NAME, "管理员名称不符合规定"); String password = admin.getPassword(); if (StringUtils.isEmpty(password) || password.length() < 6) return ResponseUtil.fail(ADMIN_INVALID_PASSWORD, "管理员密码长度不能小于6"); return null; @RequiresPermissions("admin:admin:create") @RequiresPermissionsDesc(menu = "系统管理", "管理员管理", button = "添加") @PostMapping("/create") public Object create(@RequestBody LitemallAdmin admin) Object error = validate(admin); if (error != null) return error; String username = admin.getUsername(); List<LitemallAdmin> adminList = adminService.findAdmin(username); if (adminList.size() > 0) return ResponseUtil.fail(ADMIN_NAME_EXIST, "管理员已经存在"); String rawPassword = admin.getPassword(); BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); String encodedPassword = encoder.encode(rawPassword); admin.setPassword(encodedPassword); adminService.add(admin); logHelper.logAuthSucceed("添加管理员", username); return ResponseUtil.ok(admin); @RequiresPermissions("admin:admin:read") @RequiresPermissionsDesc(menu = "系统管理", "管理员管理", button = "详情") @GetMapping("/read") public Object read(@NotNull Integer id) LitemallAdmin admin = adminService.findById(id); return ResponseUtil.ok(admin); @RequiresPermissions("admin:admin:update") @RequiresPermissionsDesc(menu = "系统管理", "管理员管理", button = "编辑") @PostMapping("/update") public Object update(@RequestBody LitemallAdmin admin) Object error = validate(admin); if (error != null) return error; Integer anotherAdminId = admin.getId(); if (anotherAdminId == null) return ResponseUtil.badArgument(); // 不允许管理员通过编辑接口修改密码 admin.setPassword(null); if (adminService.updateById(admin) == 0) return ResponseUtil.updatedDataFailed(); logHelper.logAuthSucceed("编辑管理员", admin.getUsername()); return ResponseUtil.ok(admin); @RequiresPermissions("admin:admin:delete") @RequiresPermissionsDesc(menu = "系统管理", "管理员管理", button = "删除") @PostMapping("/delete") public Object delete(@RequestBody LitemallAdmin admin) Integer anotherAdminId = admin.getId(); if (anotherAdminId == null) return ResponseUtil.badArgument(); // 管理员不能删除自身账号 Subject currentUser = SecurityUtils.getSubject(); LitemallAdmin currentAdmin = (LitemallAdmin) currentUser.getPrincipal(); if (currentAdmin.getId().equals(anotherAdminId)) return ResponseUtil.fail(ADMIN_DELETE_NOT_ALLOWED, "管理员不能删除自己账号"); adminService.deleteById(anotherAdminId); logHelper.logAuthSucceed("删除管理员", admin.getUsername()); return ResponseUtil.ok();
package org.linlinjava.litemall.admin.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE, ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermissionsDesc String[] menu(); String button();
以上是关于shiro PermissionUtil的主要内容,如果未能解决你的问题,请参考以下文章