權限設計和實現


網站開發,就會涉及到人員登錄,人員呢就會有權限。今天就理一下Springmvc的權限實現過程。

1.首先要知道@AuthPassport這個注解。這個注解能就是實現權限驗證的注解。

2.在需要驗證權限的Controller的方法上添加注解

@AuthPassport//權限驗證

@AuthPassport(validate=false)//validate默認為true,表示需要驗證,當validate 為false時表示不需要驗證

@AuthPassport(authority="common")//只有有common權限的才可以調用方法

@AuthPassport(authority = Const.AUTH_LOG)//只有有Const.AUTH_LOG常量權限的才可以調用方法

以上是我的項目中常用的權限注解方式。

3.配置項目的springservlet-config.xml或者springmvc.xml中添加如下內容:

這樣在執行每個action方法是都會調用AuthInterceptor處理,當判斷action上有我們定義AuthPassport注解時就會執行里面的權限驗證邏輯。

<mvc:interceptors>
        <!-- 國際化操作攔截器 如果采用基於(請求/Session/Cookie)則必需配置 -->
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
        <!-- 如果不定義 mvc:mapping path 將攔截所有的URL請求 -->
        <bean class="com.tj720.mip.framework.auth.AuthInterceptor"></bean>
    </mvc:interceptors>

其中第一個bean是spring-webmvc的jar包中的

另外一個bean就是自己寫的權限實現文件

package com.tj720.mip.framework.auth;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthPassport {
    boolean validate() default true;
    String authority() default "";
}
package com.tj720.mip.framework.auth;
import java.net.InetAddress;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.tj720.mip.framework.MyException;
import com.tj720.mip.inter.dao.ICacheDao;
import com.tj720.mip.springbeans.Config;
import com.tj720.mip.springbeans.GetBeanByConfig;
import com.tj720.mip.utils.Aes;
import com.tj720.mip.utils.Const;
import com.tj720.mip.utils.MyCookie;
import com.tj720.mip.utils.MyString;
import com.tj720.mip.utils.Tools;



/**
 * 對登錄狀態進行攔截
 * @author 
 *
 */
public class AuthInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private GetBeanByConfig getBEanByConfig;
    @Autowired
    private Config config;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler.getClass().isAssignableFrom(HandlerMethod.class)){
            AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class);
        
            
             // 未登陸用戶唯一識別
            String uuid = MyCookie.getCookie(Const.COOKIE_UUID, false, request);
            if( MyString.isEmpty(uuid) ){
                MyCookie.addCookie(Const.COOKIE_UUID, System.currentTimeMillis() + Tools.getChar(10), response);
            }
            
            try{
                // 返回服務器ip
                response.setHeader("serviceIp", InetAddress.getLocalHost().getHostAddress());
            }catch(Exception e){
                e.printStackTrace();
                response.setHeader("serviceIp", "服務器配置異常,無法獲取服務器IP");
            }
            
            if(authPassport == null || authPassport.validate() == false)
                return true;
            
            
            String token = MyCookie.getCookie(Const.COOKIE_TOKEN, false, request);
            String uid = MyCookie.getCookie(Const.COOKIE_USERID, false, request);
            // 前端沒有傳遞token,未登錄
            if(MyString.isEmpty(token) || MyString.isEmpty(uid) || !Aes.desEncrypt(token).equals(uid)){
                if(request.getRequestURI().endsWith("admin.do"))
                    response.sendRedirect("loginOrRegister.do#/login");
                else{
                    String acceptHeader = request.getHeader("Accept");
                    String ajaxParam = request.getParameter("text/html;type=ajax");
                    if ("text/html;type=ajax".equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
                        throw new MyException("000021");
                    } else {
                        response.sendRedirect(request.getContextPath()+"/toLogin.do");
                    }
                }
            }
            
            // 后端沒登錄信息:登錄超時
            ICacheDao cacheDao = getBEanByConfig.getCacheDao();
            Object obj = cacheDao.getObj(Const.CACHE_USER + uid);
            if(obj == null){
                // 刪除cookie
                MyCookie.deleteCookie(Const.COOKIE_TOKEN, request, response);
                if(request.getRequestURI().endsWith("admin.do")){
                    response.sendRedirect("loginOrRegister.do#/login");
                    return false;
                }
                else{
                    String acceptHeader = request.getHeader("Accept");
                    String ajaxParam = request.getParameter("text/html;type=ajax");
                    if ("text/html;type=ajax".equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
                        throw new MyException("000021");
                    } else {
                        response.sendRedirect(request.getContextPath()+"/toLogin.do");
                        return false;
                    }
                }
            }
            
            // 每次訪問,將用戶登錄有效信息延長
            cacheDao.setObj(Const.CACHE_USER + uid, obj, config.getLoginInforTime());
            
            if(!authPassport.authority().equals("")){
                return Tools.hasAuth(authPassport.authority());
            }else{
                return true;
            }
            
        }
        else
            return true;   
     }
    

}

 

4.在LoginController中

5.在LoginInfoDto中要放登陸者用到的所有信息字段

6.查出用戶的所有權限,用,分割

7.在需要的權限的方法前邊加注解

8.在jsp頁面判斷等級為3的顯示if標簽中的內容

9.判斷有edit權限的可以看到if標簽下的內容

 10.當然,在jsp頁面要加標簽

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 

 11總結思路:

首先配置spring權限驗證的配置文件,

在登錄按鈕中加方法去login方法中驗證用戶名密碼是否正確,

如果正確將user對象放到session和cookie中。

這樣在執行每個action方法是都會看有沒有@AuthPassport注解,

如果有就調用AuthInterceptor處理,執行權限驗證邏輯。

其中涉及的表是user表和auth表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM