天天看點

java 權限url權限_Spring Security 動态url權限控制(三)一、前言二、資料庫建表三、Spring Security 動态權限控制

一、前言

本篇文章将講述Spring Security 動态配置設定url權限,未登入權限控制,登入過後根據登入使用者角色授予通路url權限

基本環境

  1. spring-boot 2.1.8
  2. mybatis-plus 2.2.0
  3. mysql 資料庫
  4. maven項目

Spring Security入門學習可參考之前文章:

  1. SpringBoot內建Spring Security入門體驗(一)
  2. Spring Security 自定義登入認證(二)

二、資料庫建表

java 權限url權限_Spring Security 動态url權限控制(三)一、前言二、資料庫建表三、Spring Security 動态權限控制

表關系簡介:

  1. 使用者表t_sys_user 關聯 角色表t_sys_role 兩者建立中間關系表t_sys_user_role
  2. 角色表t_sys_role 關聯 權限表t_sys_permission 兩者建立中間關系表t_sys_role_permission
  3. 最終展現效果為目前登入使用者所具備的角色關聯能通路的所有url,隻要給角色配置設定相應的url權限即可
溫馨小提示:這裡邏輯根據個人業務來定義,小編這裡講解案例隻給使用者對應的角色配置設定通路權限,像其它的 直接給使用者配置設定權限等等可以自己實作

表模拟資料如下:

java 權限url權限_Spring Security 動态url權限控制(三)一、前言二、資料庫建表三、Spring Security 動态權限控制

三、Spring Security 動态權限控制

1、未登入通路權限控制

自定義AdminAuthenticationEntryPoint類實作AuthenticationEntryPoint類

這裡是認證權限入口 -> 即在未登入的情況下通路所有接口都會攔截到此(除了放行忽略接口)

溫馨小提示:ResponseUtils和ApiResult是小編這裡模拟前後端分離情況下傳回json格式資料所使用工具類,具體實作可參考文末給出的demo源碼
@Componentpublic class AdminAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) { ResponseUtils.out(response, ApiResult.fail("未登入!!!")); }}
           

2、自定義過濾器MyAuthenticationFilter繼承OncePerRequestFilter實作通路鑒權

每次通路接口都會經過此,我們可以在這裡記錄請求參數、響應内容,或者處理前後端分離情況下,以token換使用者權限資訊,token是否過期,請求頭類型是否正确,防止非法請求等等

  1. logRequestBody()方法:記錄請求消息體
  2. logResponseBody()方法:記錄響應消息體

【注:請求的HttpServletRequest流隻能讀一次,下一次就不能讀取了,是以這裡要使用自定義的MultiReadHttpServletRequest工具解決流隻能讀一次的問題,響應同理,具體可參考文末demo源碼實作】

@[email protected] class MyAuthenticationFilter extends OncePerRequestFilter { private final UserDetailsServiceImpl userDetailsService; protected MyAuthenticationFilter(UserDetailsServiceImpl userDetailsService) { this.userDetailsService = userDetailsService; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { System.out.println("請求頭類型: " + request.getContentType()); if ((request.getContentType() == null && request.getContentLength() > 0) || (request.getContentType() != null && !request.getContentType().contains(Constants.REQUEST_HEADERS_CONTENT_TYPE))) { filterChain.doFilter(request, response); return; } MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request); MultiReadHttpServletResponse wrappedResponse = new MultiReadHttpServletResponse(response); StopWatch stopWatch = new StopWatch(); try { stopWatch.start(); // 記錄請求的消息體 logRequestBody(wrappedRequest);// String token = "123"; // 前後端分離情況下,前端登入後将token儲存在cookie中,每次通路接口時通過token去拿使用者權限 String token = wrappedRequest.getHeader(Constants.REQUEST_HEADER); log.debug("背景檢查令牌:{}
           

繼續閱讀