登錄攔截兄弟篇權限攔截

權限攔截

思路解析

一.閱讀本篇之前,可以先提前瞭解小編在之前寫過的登錄攔截的那篇博客。有助於更好的理解本篇權限攔截。
二.權限攔截思路解析:獲取用戶訪問路徑uri
1.首先遍歷所有的權限判斷其中是否包含該uri,如果不包含則不需要攔截(比如:userController/login )比如這個登錄方法的路徑訪問時就不需要攔截,即我們只攔截所有權限裏的路徑,因此在數據庫編寫路權限徑時注意區分大小寫,及不能漏掉要攔截的權限路徑。如果包含則需要判斷該用戶是否有對應權限。
2.當所有的權限包含該uri時,判斷該用戶的權限列表是否有對應權限。如有則說明該用戶訪問的路徑他有權利去訪問和之後的相關操作,不需要攔截。如果用戶權限列表沒有該uri說明用戶不具備此權限,需要攔截該用戶。
3.當需要攔截該用戶時,就和登錄攔截很相似,需要判斷是不是ajax請求並返回相應提示信息給用戶。

準備工作

如上所述,權限攔截需要如下“工具”:
1.permissionListAll 所有的權限列表

public List<Permission> queryPermissionList() {
		return permissionRepository.findAll();
	}

通過JpaRepository接口自帶的查詢方法查出所有權限列表。

2.permissionListByUserId 用戶的權限列表

@Query(nativeQuery = true,value = "select DISTINCT tp.* FROM t_user_role_new tur LEFT JOIN t_role_permission_new trp ON tur.roleId = trp.roleId LEFT JOIN t_permission_new tp on trp.permissionId = tp.id where tur.userId = ?1")
	List<Permission> findPermissionListByUserId(Integer userId);

爲了提高性能小編是通過三表聯查獲得用戶權限:通過用戶id查詢,用戶_角色關聯表左聯角色_權限關聯表左聯權限表,通過三表聯查查詢到該用戶id對應的所有權限。

3.String uri = request.getRequestURI(); 用戶訪問的地址欄路徑。(URI,統一資源標誌符(Uniform Resource Identifier, URI),表示的是web上每一種可用的資源,如 HTML文檔、圖像、視頻片段、程序等都由一個URI進行定位的。)

具體實現

新建一個PermissionInterceptor基礎HandlerInterceptorAdapter並重寫preHandle方法。

package com.fh.interceptor;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.fh.model.Permission;
import com.fh.util.JsonUtil;

public class PermissionInterceptor extends HandlerInterceptorAdapter{

	@SuppressWarnings("unchecked")
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session = request.getSession();
		/*
		 * 登陸成功後login方法已經將permissionListByUserId,
		 * permissionListAll放入session裏,所以我們只需要從session中取出即可
		 */
		List<Permission> permissionListByUserId = (List<Permission>) session.getAttribute("permissionListByUserId");
		List<Permission> permissionListAll = (List<Permission>) session.getAttribute("permissionListAll");
		
		String uri = request.getRequestURI();// 類似於userController/addUser
		
		if(StringUtils.isBlank(uri)) {//如果uri爲空則不需要攔截
			return true;
		}
		boolean contains = false;
		/*
		 * 立一個flag(contains) 若flag(contains)爲true表明所有權限包含該uri,
		 * 一旦包含即可break提高代碼性能。
		 */
		if(permissionListAll != null && permissionListAll.size() > 0) {
			for (Permission permission : permissionListAll) {
				if(StringUtils.isNotBlank(permission.getUrl()) && uri.contains(permission.getUrl())) {
					contains = true;
					break;
				}
			}
		}
		if(contains == false) {//若flag(contains)爲false表明所有權限列表如果不包含則不需要攔截
			return true;
		}else {//表明所有權限permissionListAll包含該uri,就需要進一步驗證用戶權限是否包含
			boolean hasPermission = false;
			/*
			 * 當所有的權限包含該uri時,判斷該用戶的權限列表是否有對應權限。
			 * 如有則說明該用戶訪問的路徑他有權利去訪問和之後的相關操作,不需要攔截。
			 * 如果用戶權限列表沒有該uri說明用戶不具備此權限,需要攔截該用戶。
			 * 
			 */
			if(permissionListByUserId != null && permissionListByUserId.size() > 0) {
				for (Permission permission : permissionListByUserId) {
					if(StringUtils.isNotBlank(permission.getUrl()) && uri.contains(permission.getUrl())) {
						hasPermission = true;
						break;
					}
				}
			}
			if(hasPermission == true) {//在permissionListAll裏邊,且有用戶權限。允許用戶訪問。
				return true;
			}else {//用戶權限列表沒有該uri說明用戶不具備此權限,需要攔截該用戶
				String header = request.getHeader("X-Requested-With");
				//根據請求頭部判斷是不是ajax請求
				if(StringUtils.isNotBlank(header) && header.equals("XMLHttpRequest")) {
					//是ajax請求就要給前端頁面一個信號,在前端頁面判斷後可以再彈出提示信息,跳到指定頁面
					Map<String, Object> result = new HashMap<String, Object>();
					result.put("code", 2000);
					JsonUtil.outJson(response, result);
				}else {//不是ajax請求可以直接重定向到指定頁面
					response.sendRedirect(request.getServletContext().getContextPath()+"/no-permission.jsp");
				}
				return false;
			}
		}
		
	}
}

springMVC.xml配置

<mvc:interceptor>
				<mvc:mapping path="/**" />
				/*
				*配置白名單,放開靜態資源
				*/
				<mvc:exclude-mapping path="/js/**" />
				<mvc:exclude-mapping path="/bootstrap/**" />
				
				<bean class="com.fh.interceptor.PermissionInterceptor"></bean>
</mvc:interceptor> 

寫在最後

本篇爲小編和人理解所作,如有錯誤請聯繫小編進行修改或刪除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章