Spring Security許可權控制系列(一)

環境:Springboot2。4。12 + Spring Security 5。4。9

本篇主要內容是基於記憶體的配置

引入依賴

org。springframework。boot spring-boot-starter-security

自定義使用者配置

spring: security: user: name: admin password: 123456

定義Controller介面

@RestController@RequestMapping(“/demos”)public class DemoController { @GetMapping(“home”) public Object home() { return “demos home” ; }}

訪問:http://localhost:8080/demos/home

將會自動跳轉到預設地登入頁面

Spring Security許可權控制系列(一)

使用配置檔案中配置的admin/123123進行登入

Spring Security許可權控制系列(一)

沒有任何問題

再定義一個POST介面

@PostMapping(“post”)public Object post() { return “demos post” ;}

注意:這裡我們透過Postman訪問預設的登入

/login

介面先進行登入,登入完成後我們在訪問這個post介面。(記住我們在上面訪問的GET /demos/home介面只要登入後就可以繼續訪問該介面)

Spring Security許可權控制系列(一)

首次登入時注意返回的登入頁面的html內容,表單資訊中多了一個隱藏域

_csrf

欄位,如果我們透過Postman模擬登入時如果不帶上該欄位將無法登入。

Spring Security許可權控制系列(一)

修改登入資訊新增上

_csrf

表單欄位,再進行登入

Spring Security許可權控制系列(一)

這裡返回404狀態碼是由於我們沒有配置預設登入成功頁

到此在Postman中就登入成功了,接下來咱們繼續透過Postman訪問

GET

/demos/home

介面

Spring Security許可權控制系列(一)

直接訪問沒有任何問題

接著訪問上面定義的

POST /demos/post

介面

Spring Security許可權控制系列(一)

服務端返回403拒絕訪問,上面GET方式正常,POST出現該異常,接著將上面我們登入時候的

_csrf

欄位一起進行提交。

Spring Security許可權控制系列(一)

針對POST請求必須攜帶正確的

_csrf

資訊才能繼續方法。

實現原理

在預設情況下Security會新增CsrfFilter過濾器

public final class CsrfFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 從預設的HttpSessionCsrfTokenRepository中獲取token,預設是從session中 CsrfToken csrfToken = this。tokenRepository。loadToken(request); boolean missingToken = (csrfToken == null); if (missingToken) { // 如果當前session不存在則生成token csrfToken = this。tokenRepository。generateToken(request); // 如果csrfToken不為null,則這裡什麼都不做(不會儲存) this。tokenRepository。saveToken(csrfToken, request, response); } // 。。。 // 判斷當前的請求方法是否是(“GET”, “HEAD”, “TRACE”, “OPTIONS”) // 如果是上面的Method則直接放行,否則繼續往下執行 if (!this。requireCsrfProtectionMatcher。matches(request)) { filterChain。doFilter(request, response); return; } // 從請求header中獲取_csrf值,headerName = X-CSRF-TOKEN String actualToken = request。getHeader(csrfToken。getHeaderName()); if (actualToken == null) { // 如果header中不存在,則從請求引數中獲取 parameterName = _csrf actualToken = request。getParameter(csrfToken。getParameterName()); } // 判斷當前引數中的token值與儲存到當前session中的是否想到,不等則返回403錯誤 if (!equalsConstantTime(csrfToken。getToken(), actualToken)) { AccessDeniedException exception = (!missingToken) ? new InvalidCsrfTokenException(csrfToken, actualToken) : new MissingCsrfTokenException(actualToken); this。accessDeniedHandler。handle(request, response, exception); return; } filterChain。doFilter(request, response); }}

一般我們都會關閉csrf功能

@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 關閉csrf,就是刪除CsrfFilter過濾器。 http。csrf()。disable() ; // 攔截任意請求 http。authorizeRequests()。anyRequest()。authenticated() ; // 這裡需要加上該句,否則不會出現登入頁面 http。formLogin() ; }}

以上是關於Spring Security預設配置的情況下csrf相關問題。接下來透過自定義類配置來設定使用者的使用者資訊。

自定義配置

@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter { @SuppressWarnings(“deprecation”) @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 這在後續的文章中會介紹該方法的具體使用 // super。configure(auth); // 配置使用者名稱密碼角色,及密碼編碼方式 auth。inMemoryAuthentication()。passwordEncoder(NoOpPasswordEncoder。getInstance())。withUser(“guest”)。password(“123456”)。roles(“ADMIN”) ; } @Override protected void configure(HttpSecurity http) throws Exception { http。csrf()。disable() ; http。authorizeRequests()。anyRequest()。authenticated() ; http。formLogin() ; }}

透過上面配置後,在進行授權的時候就需要使用這裡的配置資訊。

本篇介紹到這裡,下篇將介紹具體的請求攔截配置及自定義登入頁面等功能更。

SpringBoot對Spring MVC都做了哪些事?(一)

SpringBoot對Spring MVC都做了哪些事?(二)

SpringBoot對Spring MVC都做了哪些事?(三)

SpringBoot對Spring MVC都做了哪些事?(四)

Spring事務實現原理原始碼分析

Spring中的@Configuration註解你真的瞭解嗎?

Spring Retry重試框架的應用

spring data jpa 高階應用

Spring容器這些擴充套件點你都清楚了嗎?

Spring Security許可權控制系列(一)

Spring Security許可權控制系列(一)

Spring Security許可權控制系列(一)

Spring Security許可權控制系列(一)