版权声明:本文为博主原创文章,未经博主容许不得转载。程序员
最近公司布置了一个任务,经过springMVC注解来控制一个请求的权限;因为以前没有接触过注释控制权限,此次尝试了;效果还不是特别好;只能进行简单的权限管理,固然这只是初版,确定后面要修改不少方面,但愿大神们多多指导;web
权限这没用用到最近比较火的shiro框架,仍是基于RBAC模型 ,有六张表;spring
用户表 user 角色表 菜单表 资源表 还有2张关系表 数据库
①自定义注解(目前为了简单只定义了一个注解,后期还要再加):mvc
//用于约束被描述的注解的使用范围,当被描述的注解超出使用范围则编译失败。 @Target(ElementType.METHOD) //做用范围为运行时,就是咱们能够经过反射动态获取该注解。 @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermission { String value() default "user"; }
②写拦截器(注:目前尚未处理没有权限的跳转页面)app
public class RequiresPermissionInterceptor extends HandlerInterceptorAdapter { @Autowired private PermissionService permissionService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler.getClass().isAssignableFrom(HandlerMethod.class)) { //经过反射获得权限的角色 //角色分为三种 user:用户 admin:管理员 superAdmin:超级管理员 RequiresPermission permission = ((HandlerMethod) handler).getMethodAnnotation(RequiresPermission.class); String value = permission.value(); System.out.print("角色"+value); //经过反射拿到requestMapping 里面的value参数 RequestMapping annotation=((HandlerMethod) handler).getMethodAnnotation(RequestMapping.class); System.out.print(annotation.toString()); String[] rm= annotation.value(); //拿到当前请求的地址 String url =request.getServletPath(); String wholeUrl=""; for (int i=0;i<rm.length;i++){ wholeUrl = splitString(url)+rm[i]; System.out.println("wholeUrl完整的url是:"+wholeUrl); } //没有注明权限 或者权限为user 则都默认为用户的权限 if (permission == null || "user".equals(value) ) { System.out.println("我进来了"); //得到用户的roleType Integer roleType =RoleTypeConstant.ROLE_USER; System.out.println("用户的roleType"+roleType); RoleFunction roleFunction =permissionService.findByUrlAndCode(wholeUrl,roleType); if(roleFunction!=null){ return true; } }else if ("admin".equals(value)){ //得到管理员的roleType Integer roleType =RoleTypeConstant.ROLE_ADMIN; System.out.println("管理员的roleType"+roleType); RoleFunction roleFunction =permissionService.findByUrlAndCode(wholeUrl,roleType); if(roleFunction!=null){ return true; } }else if ("superAdmin".equals(value)){ //得到超级管理员的roleType Integer roleType =RoleTypeConstant.ROLE_SUPER_ADMIN; System.out.println("超级管理员的roleType"+roleType); RoleFunction roleFunction =permissionService.findByUrlAndCode(wholeUrl,roleType); if(roleFunction!=null){ return true; } } } return false; } //截取字符串 private String splitString(String url){ //得到第二个/的下标 int subscript= url.indexOf("/",2) ; System.out.println("subscript"+subscript); //截取第二个/前面的字符串 String subUrl= url.substring(0,subscript); System.out.println("SubUrl是"+subUrl); return subUrl; } }
注:RoleTypeConstant调用的方法框架
public class RoleTypeConstant { /** * 超级管理员帐户 */ public static final Integer ROLE_SUPER_ADMIN = 1; /** * 普通管理员帐户 */ public static final Integer ROLE_ADMIN = 2; /** * 普通注册用户帐户 */ public static final Integer ROLE_USER = 3; public static String getTypeName(Integer roleType){ String typeName = ""; switch (roleType){ case 1 : typeName = "超级管理员"; break; case 2 : typeName = "普通管理员"; break; case 3 : typeName = "普通注册用户"; break; } return typeName; }
注:service层的实现ide
@Service("permissionService") public class PermissionServiceImpl implements PermissionService{ @Autowired private PermissionDomainService permissionDomainService; @Override public RoleFunction findByUrlAndCode(String url,Integer roleType) { //若是地址为直接返回用户的权限 if (url!=null){ System.out.println("url" +url); //经过查找url得到function对象 Function function =permissionDomainService.findFunctionByUrl(url); System.out.println("function" +function.getCode()); // 经过url得到用户惟一的code Integer code = function.getCode(); if (code!=null ){ //经过得到code 和 roleType 判断RoleFunction是否为null //roleType 分为三种 1:超级管理员 2:管理员 3:用户 RoleFunction roleFunction =permissionDomainService.findByCode(code,roleType); return roleFunction; } } return null; } }
dao层(实现方式不一样,这里我只说明接口)测试
public interface PermissionDao { //经过url得到用户惟一的code public Function queryFunctionByUrl(String url); //经过code 得到用户的rolType 从而控制权限 //roleType 分为三种 1:超级管理员 2:管理员 3:用户 public RoleFunction queryByCode(Integer code,Integer roleType); }
③配置文件里添加扫描拦截器ui
<mvc:interceptors> <!-- 国际化操做拦截器 若是采用基于(请求/Session/Cookie)则必需配置 --> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> <!-- 若是不定义 mvc:mapping path 将拦截全部的URL请求 --> <!--拦截器处理用户登录的权限 --> <!--<bean class="com.zhongqi.permission.Intercepter.RequiresUserInterceptor"></bean>--> <!--拦截器处理资源的权限 --> <bean class="com.zhongqi.permission.Intercepter.RequiresPermissionInterceptor"></bean> </mvc:interceptors>
控制层的测试()
@Controller @RequestMapping("/match") public class PermissionController extends BaseController { @Autowired private PermissionService permissionService; /** * 测试 从数据库的资源列表查找 * user 的权限 /user/loginOut * 管理员特有的权限 /match/modifyMatchEvent * 超级管理员特有的权限 * * * @param response */ @RequiresPermission("user") @RequestMapping("/loginOut") private void PermissionText1(HttpServletResponse response){ JsonResponseResult result = new JsonResponseResult(); result.setCode(1); result.setMsg("输入正确"); //公司内部封装 response(BaseUtils.toJsonFromObject(result), response); } @RequiresPermission("user") @RequestMapping("/modifyMatchEvent") private void PermissionText2(HttpServletResponse response){ JsonResponseResult result = new JsonResponseResult(); result.setCode(1); result.setMsg("输入正确"); //公司内部封装 response(BaseUtils.toJsonFromObject(result), response); } @RequiresPermission("superAdmin") @RequestMapping("/pt3") private void PermissionText3(HttpServletResponse response){ JsonResponseResult result = new JsonResponseResult(); result.setCode(1); result.setMsg("输入正确"); //公司内部封装 response(BaseUtils.toJsonFromObject(result), response); }
注:目前只是简单的实现了权限控制,还有不少问题没有解决,由于这只是一我的的想法,还有注释里面的参数应该能够再丰富些。目前注释里面只有三个参数,或者不填;经过里面的注释能够判断这个请求是否能够继续下去,就是拦截器;
刚刚开始作,写的特别low,但愿大神们多多指导。后期会持续更新改版后的权限管理,欢迎你们访问,但愿给刚入手的程序员有所帮助。
2016 /09/09