1. 程式人生 > >詳解Spring Security的formLogin登入認證模式

詳解Spring Security的formLogin登入認證模式

一、formLogin的應用場景

在本專欄之前的文章中,已經給大家介紹過Spring Security的HttpBasic模式,該模式比較簡單,只是進行了通過攜帶Http的Header進行簡單的登入驗證,而且沒有定製的登入頁面,所以使用場景比較窄。
對於一個完整的應用系統,與登入驗證相關的頁面都是高度定製化的,非常美觀而且提供多種登入方式。這就需要Spring Security支援我們自己定製登入頁面,也就是本文給大家介紹的formLogin模式登入認證模式。

準備工作

  • 新建一個Spring Boot 的web應用,引入Spring Security Starter。
  • 準備一個login.html登入頁面,頁面內容非常簡單,一個from表單、使用者名稱和密碼輸入框,一個提交按鈕
  • 準備一個首頁index.html,在登入成功之後需要進入index.html首頁
  • 首頁可以看到syslog(日誌管理)、sysuer(使用者管理)、biz1(業務一)、biz2(業務二)四個頁面超文字連結選項。通過controller控制層跳轉頁面,並在對應頁面寫一些標誌性文字即可,不需寫具體業務。

需求

  • 我們希望biz1(業務一)、biz2(業務二)普通的操作使用者user就可以訪問
  • 我們希望管理員可以訪問包括syslog(日誌管理)和sysuser(使用者管理)在內的所有資源

以上就是本文介紹formLogin模式需要進行的準備工作及需求,下面我們就來實現其中的核心的登入驗證邏輯,準備工作非常簡單請自行實現。(新建spring boot應用,登入頁面、首頁、四個業務頁面都寫成非常簡單的html即可,不用寫實際業務和樣式。)

二、說明

formLogin模式的三要素:

  • 登入驗證邏輯
  • 資源訪問控制規則,如:資源許可權、角色許可權
  • 使用者資訊

一般來說,使用許可權認證框架的的業務系統登入驗證邏輯是固定的,而資源訪問控制規則和使用者資訊是從資料庫或其他儲存介質靈活載入的。但本文所有的使用者、資源、許可權資訊都是程式碼配置寫死的,旨在為大家介紹formLogin認證模式,如何從資料庫載入許可權認證相關資訊我還會結合RBAC許可權模型再寫文章的。

三、實現formLogin模式基礎配置

首先,我們要繼承WebSecurityConfigurerAdapter ,重寫configure(HttpSecurity http) 方法,該方法用來配置登入驗證邏輯。請注意看下文程式碼中的註釋資訊。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable() //禁用跨站csrf攻擊防禦,後面的章節會專門講解
            .formLogin()
                .loginPage("/login.html")//使用者未登入時,訪問任何資源都轉跳到該路徑,即登入頁面
                .loginProcessingUrl("/login")//登入表單form中action的地址,也就是處理認證請求的路徑
                .usernameParameter("uname")///登入表單form中使用者名稱輸入框input的name名,不修改的話預設是username
                .passwordParameter("pword")//form中密碼輸入框input的name名,不修改的話預設是password
                .defaultSuccessUrl("/index")//登入認證成功後預設轉跳的路徑
                .and()
            .authorizeRequests()
                .antMatchers("/login.html","/login").permitAll()//不需要通過登入驗證就可以被訪問的資源路徑
                .antMatchers("/biz1").hasAnyAuthority("biz1")  //前面是資源的訪問路徑、後面是資源的名稱或者叫資源ID
                .antMatchers("/biz2").hasAnyAuthority("biz2")
                .antMatchers("/syslog").hasAnyAuthority("syslog")
                .antMatchers("/sysuser").hasAnyAuthority("sysuser")
                .anyRequest().authenticated();
    }
    
}

上面的程式碼分為兩部分:

  • 第一部分是formLogin配置段,用於配置登入驗證邏輯相關的資訊。如:登入頁面、登入成功頁面、登入請求處理路徑等。
  • 第二部分是authorizeRequests配置端,用於配置資源的訪問許可權。如:開發登入頁面的permitAll開放訪問,“/biz1”(業務一頁面資源)需要有資源ID為"biz1"的使用者才可以訪問。

這時候,我們通過瀏覽器訪問,隨便測試一個沒有訪問許可權的資源,都會跳轉到login.html頁面。

四、實現資源訪問限制的需求

在上文中,我們配置了登入驗證及資源訪問的許可權規則,我們還沒有具體的使用者,下面我們就來配置具體的使用者。重寫WebSecurityConfigurerAdapter的 configure(AuthenticationManagerBuilder auth)方法

public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("user").password(passwordEncoder().encode("123456")).authorities("biz1","biz2")
        .and()
        .passwordEncoder(passwordEncoder());//配置BCrypt加密
}

@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}
  • inMemoryAuthentication指的是在記憶體裡面儲存使用者的身份認證和授權資訊。
  • withUser("user")使用者名稱是user
  • password(passwordEncoder().encode("123456"))密碼是加密之後的123456
  • authorities("biz1","biz2")指的是user使用者擁有資源ID為biz1(業務一)和biz2(業務二)資源的許可權

這樣,我們就實現了文首提出的普通使用者只能訪問biz1(業務一)和biz2(業務二)資源的需求。那麼管理員使用者可以訪問所有的資源的配置方式,你會不會呢?同樣的配方、同樣的方式、自己可以嘗試一下哦!

五、靜態資源訪問

在我們的實際開發中,登入頁面login.html和控制層Controller登入驗證'/login'都必須無條件的開放。除此之外,一些靜態資源如css、js檔案通常也都不需要驗證許可權,我們需要將它們的訪問許可權也開放出來。下面就是實現的方法:重寫WebSecurityConfigurerAdapter類的configure(WebSecurity web) 方法


   @Override
    public void configure(WebSecurity web) {
        //將專案中靜態資源路徑開放出來
        web.ignoring().antMatchers("/config/**", "/css/**", "/fonts/**", "/img/**", "/js/**");
    }

期待您的關注

  • 博主最近新寫了一本書:《手摸手教您學習SpringBoot系列-16章97節》
  • 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格。