天天看點

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

1. Spring Security簡介

Spring Security 的前身是 Acegi Security,在被收納為Spring子項目後正式更名為Spring Security。

應用程式的安全性通常展現在兩個方面:認證和授權。

  • 認證是确認某主體在某系統中是否合法、可用的過程。這裡的主體既可以是登入系統的使用者,也

    可以是接入的裝置或者其他系統。

  • 授權是指當主體通過認證之後,是否允許其執行某項操作的過程。

這些概念并非Spring Security獨有,而是應用安全的基本關注點。Spring Security可以幫助我們更便

捷地完成認證和授權。

Spring Security 支援廣泛的認證技術,這些認證技術大多由第三方或相關标準組織開發。Spring

Security 已經內建的認證技術如下:

◎ HTTP BASIC authentication headers:一個基于IETF RFC的标準。

◎ HTTP Digest authentication headers:一個基于IETF RFC的标準。

◎ HTTP X.509 client certificate exchange:一個基于IETF RFC的标準。

◎ LDAP:一種常見的跨平台身份驗證方式。

◎ Form-based authentication:用于簡單的使用者界面需求。

◎ OpenID authentication:一種去中心化的身份認證方式。

◎ Authentication based on pre-established request headers:類似于 Computer Associates SiteMinder,一種使用者身份驗證及授權的集中式安全基礎方案。

◎ Jasig Central Authentication Service:單點登入方案。

◎ Transparent authentication context propagation for Remote Method Invocation(RMI) and HttpInvoker:一個Spring遠端調用協定。

◎ Automatic “remember-me” authentication:允許在指定到期時間前自行重新登入系統。

◎ Anonymous authentication:允許匿名使用者使用特定的身份安全通路資源。

◎ Run-as authentication:允許在一個會話中變換使用者身份的機制。

◎ Java Authentication and Authorization Service:JAAS,Java驗證和授權API。

◎ Java EE container authentication:允許系統繼續使用容器管理這種身份驗證方式。

◎ Kerberos:一種使用對稱密鑰機制,允許用戶端與伺服器互相确認身份的認證協定。

除此之外,Spring Security還引入了一些第三方包,用于支援更多的認證技術,如JOSSO等。如果

所有這些技術都無法滿足需求,則Spring Security允許我們編寫自己的認證技術。是以,在絕大部分情 況下,當我們有Java應用安全方面的需求時,選擇Spring Security往往是正确而有效的。

在授權上,Spring Security不僅支援基于URL對Web的請求授權,還支援方法通路授權、對象通路授權等,基本涵蓋常見的大部分授權場景。

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

2. 建立項目工程

2.1 修改pom.xml配置檔案

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>           

複制

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

引入security包後,可以看到自動引入spring-security-web和spring- security -config、spring- security -aop兩個核心子產品,這正是官方建議引入的Sp ring Security最小依賴

2.2 添加路由

@GetMapping("/")
@ResponseBody
public String test2() {
    return "hello , Java技術債務!";
}           

複制

2.3 啟動工程

通路http://127.0.0.1:8705/

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

在引入Spring Security項目之後,雖然沒有進行任何相關的配置或編碼,但Spring Security有一個默 認的運作狀态,要求在經過HTTP基本認證後才能通路對應的URL資源,其預設使用的使用者名user, 密碼則是動态生成并列印到控制台的一串随機碼。翻看控制台的列印資訊,可以看到

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

輸入使用者名和密碼後,單擊“登入”按鈕即可成功通路頁面

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

當然,右HTTP基本認證中,使用者名和密碼都是可以配置的,最常見的就是在resources下的配置文 件中修改。

spring.security.user.name=1
spring.security.user.password=1           

複制

重新啟動程式,發現控制台不再列印預設密碼串了,此時使用我們自定義的使用者名和密碼即可登入。

事實上,絕大部分Web應用都不會選擇HTTP基本認證這種認證方式,除安全性差、無法攜帶cookie等因素外,靈活性不足也是它的一個主要缺點。通常大家更願意選擇表單認證,自己實作表單登入頁和驗證邏輯,進而提高安全性。

3. 自定義表單認證

3.1 建立配置檔案

WebSecurityConfig.java

package com.cuizb.cloud.alibaba.gtw.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author: Java技術債務
 * @Date: 2021/6/5 18:45
 * Describe: SpringSecurity配置
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public void configure(HttpSecurity http) throws Exception {
        log.info("Using de fault configure(HttpSecurity).If subclassed this will potentially override subclass configure(HttpSecurity) .");
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .loginPage("/blog-web/login").permitAll()
                .and()
                .csrf().disable();
    }
}           

複制

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證

3.2 HttpSecurity

HttpSecurity實際上對應了Spring Security命名空間配置方式中XML檔案内的标簽,允許我們為特 定的HTTP請求配置安全政策。

HttpSecurity提供了很多配置相關的方法,分别對應命名空間配置中的子标簽。例如authorizeRequests()、formLogin()、httpBasic()和 csrf()分别對應、、和标簽。調用這些方法之後,除非使用and()方法結束目前标簽,上下文 才會回到HttpSecurity,否則鍊式調用的上下文将自動進入對應标簽域。

authorizeRequests()方法實際上傳回了一個 URL 攔截注冊器,我們可以調用它提供的 anyanyRequest()、antMatchers()和regexMatchers()等方法來比對系統的URL,并為其指定安全 政策。

formLogin()方法和httpBasic()方法都聲明了需要Spring Security提供的表單認證方式,分别返 回 對 應 的 配 置 器 。 其 中 , f o r m L o gi n ( ) . l o gi n P a ge ( “ / m y L o gi n . h t m l “ ) 指 定 自 定 義 的 登 錄 頁/myLogin.html,同時,Spring Security會用/myLogin.html注冊一個POST路由,用于接收登入請求。

csrf()方法是Spring Security提供的跨站請求僞造防護功能,當我們繼承 WebSecurityConfigurerAdapter時會預設開啟csrf()方法。關于csrf()方法的更多内容會在後面的章節專門探讨,以使測試 程序更加順利。

3.3 其他表單配置項

package com.cuizb.cloud.alibaba.gtw.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author: Java技術債務
 * @Date: 2021/6/5 18:45
 * Describe: SpringSecurity配置
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    public void configure(HttpSecurity http) throws Exception {
        log.info("Using de fault configure(HttpSecurity).If subclassed this will potentially override subclass configure(HttpSecurity) .");
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .loginPage("/blog-web/login")
                .loginProcessingUrl("/blog-web/userLogin")
                .successHandler(new UserAuthenticationSuccessHandler())
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                        response.setStatus(401);
                        PrintWriter writer = response.getWriter();
                        writer.write("fail");
                    }
                })
                .permitAll()
                .and()
                .csrf().disable();
    }
}           

複制

表單登入配置子產品提供了 successHandler()和 failureHandler()兩個方法,分别處理登入成功和 登入失敗的邏輯。其中,successHandler()方法帶有一個Authentication參數,攜帶目前登入使用者及其角色等資訊;而failureHandler()方法攜帶一個AuthenticationException異常參數。具體處理方式需按照系統的情況自定義。

Spring Security初識和表單認證(一)1. Spring Security簡介2. 建立項目工程3. 自定義表單認證