Spring MVC系列(三):基于注解的權限控制

在Java EE項目中,權限控制是經(jīng)常遇到的問題。尤其是在多角色的系統(tǒng)中,權限控制的粒度更細,也更為重要。

問題描述

系統(tǒng)中有三種角色,教師,管理員,學生,角色權限部分交叉。如果將權限控制的邏輯添加到每一個接口,代碼冗雜且不易擴展,維護。我們將權限控制部分單獨分離出來,并使用非侵入式的方法為每一個接口添加權限。

解決方案

  • 注解:利用Java的注解機制,在運行時得到接口的權限信息。
  • AOP:Spring MVC提供了攔截器功能,本質(zhì)上是AOP。通過攔截器在處理請求前統(tǒng)一檢驗權限,在不改變業(yè)務代碼的基礎上添加了權限控制。

實現(xiàn)

學生權限:StudentPermission

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface StudentPermission {}

還定義了教師權限(TeacherPermission)、管理員權限(AdminPermission)、自身權限(SelfPermission)。這里只定義空注解,起標記作用。

添加攔截器:PermissionsInterceptor

public class PermissionsInterceptor extends HandlerInterceptorAdapter{
    
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        boolean isPass=true;
        if(method.getAnnotation(TeacherPermission.class)!=null){
            isPass=isTeacher(request);
        }
        if(method.getAnnotation(StudentPermission.class)!=null){
            isPass=isStudent(request);
        }
        if(method.getAnnotation(AdminPermission.class)!=null){
            isPass=isAdmin(request);
        }
        if(method.getAnnotation(SelfPermission.class)!=null){
            isPass=isSelf(request);
        }
        if(!isPass){//未授權,返回401信息
            Gson gson=new Gson();
            ResponseJson json=new ResponseJson();
            json.setCode(UNAUTHORIZED.getCode());
            json.setMessage(UNAUTHORIZED.getMessage());
            response.setCharacterEncoding("UTF-8");  
            response.getWriter().write(gson.toJson(json));
        }
        return isPass;
    }
    private boolean isTeacher(HttpServletRequest request){
        //判斷是否是老師
    }
    private boolean isStudent(HttpServletRequest request){
        //判斷是否是學生
    }
    private boolean isAdmin(HttpServletRequest request){
        //判斷是否是管理員
    }
    private boolean isSelf(HttpServletRequest request){
        //判斷是否是自身
    }
}

配置攔截器

<mvc:interceptors>
    </mvc:interceptor>
    <!-- 權限攔截器 -->
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <bean class="cqupt.nmid.foreign.interceptor.PermissionsInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

注解接口

在需要權限控制的接口添加注釋
@TeacherPermission
@RequestMapping(value="/students/{id}",method=RequestMethod.GET)
@ResponseBody
public ResponseJson getStudentsInfo(@PathVariable(value="id") int studentId) {
   return studentService.getStudentsInfo(studentId);
}

總結(jié)

使用注解和攔截器可以很輕松的實現(xiàn)權限控制,這里只是寫個例子,只適合簡單的權限控制,但是流程已經(jīng)制定好,可以很簡單的進行擴展。如果權限的驗證機制比較復雜,例如App接口的token加密驗證,單獨實現(xiàn)一個權限模塊再利用攔截器進行請求分發(fā)可能是更好的方式。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評論 19 139
  • 題目1: 說說庫和框架的區(qū)別? 庫是一個數(shù)據(jù)倉庫,里面放了各種可以利用的API,由于庫的內(nèi)部已經(jīng)做了各種底層的封裝...
    YASINCHAN閱讀 227評論 0 0
  • 生命的脆弱超乎想象,脆弱到如路邊的泥土一踩就散一捏就碎。 我亂翻著QQ好友,看到了一位高中同學的灰...
    胥大米閱讀 454評論 0 0
  • 取這標題僅因為我現(xiàn)在正翻開著李爾王的話劇劇本第七章the heart of the gold。 晚飯就吃個番薯?蘋...
    timowwy閱讀 468評論 0 0

友情鏈接更多精彩內(nèi)容