版權聲明:本文爲博主原創文章,未經博主容許不得轉載。程序員
最近公司佈置了一個任務,經過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