最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security AuthenticationManager 接口詳解與實(shí)戰(zhàn)

 更新時(shí)間:2025年10月22日 15:10:16   作者:小猿、  
Spring Security框架中的AuthenticationManager接口是認(rèn)證體系的核心,負(fù)責(zé)驗(yàn)證用戶身份,本文就來詳細(xì)的介紹一下這一接口的工作原理、應(yīng)用場景,感興趣的可以了解一下

概述

在 Spring Security 框架中,AuthenticationManager 接口扮演著核心角色,負(fù)責(zé)處理認(rèn)證請求并決定用戶身份是否合法。本文將詳細(xì)講解這一接口的工作原理、應(yīng)用場景,并結(jié)合 Spring Boot 3.4.3 版本提供實(shí)戰(zhàn)示例。

AuthenticationManager 接口概述

AuthenticationManager 是 Spring Security 認(rèn)證體系的核心接口,位于 org.springframework.security.authentication 包下,其定義非常簡潔:

public interface AuthenticationManager {
    Authentication authenticate(Authentication authentication) 
        throws AuthenticationException;
}

該接口僅包含一個(gè)方法 authenticate(),用于處理認(rèn)證請求,其工作流程如下:

  1. 接收一個(gè) Authentication 對象作為參數(shù),該對象包含用戶提交的認(rèn)證信息(如用戶名 / 密碼)
  2. 執(zhí)行認(rèn)證邏輯
  3. 認(rèn)證成功時(shí),返回一個(gè)包含完整用戶信息和權(quán)限的 Authentication 對象
  4. 認(rèn)證失敗時(shí),拋出 AuthenticationException 異常

核心實(shí)現(xiàn)類

在實(shí)際應(yīng)用中,我們通常不會(huì)直接實(shí)現(xiàn) AuthenticationManager 接口,而是使用其現(xiàn)成的實(shí)現(xiàn)類:

  1. ProviderManager

    • 最常用的實(shí)現(xiàn)類
    • 委托一個(gè)或多個(gè) AuthenticationProvider 實(shí)例處理認(rèn)證請求
    • 支持多種認(rèn)證機(jī)制并存
  2. AuthenticationProvider

    • 不是 AuthenticationManager 的實(shí)現(xiàn)類,而是由 ProviderManager 調(diào)用
    • 每個(gè) AuthenticationProvider 處理特定類型的認(rèn)證請求
  3. DaoAuthenticationProvider

    • 常用的 AuthenticationProvider 實(shí)現(xiàn)
    • 通過 UserDetailsService 獲取用戶信息并驗(yàn)證密碼

工作原理

AuthenticationManager 的認(rèn)證流程可概括為:

  1. 客戶端提交認(rèn)證信息(如用戶名 / 密碼)
  2. 認(rèn)證信息被封裝成 Authentication 對象
  3. AuthenticationManager 接收該對象并調(diào)用 authenticate() 方法
  4. ProviderManager 會(huì)遍歷其配置的 AuthenticationProvider 列表
  5. 找到支持當(dāng)前 Authentication 類型的 AuthenticationProvider 并委托其進(jìn)行認(rèn)證
  6. 認(rèn)證成功后,返回包含完整信息的 Authentication 對象
  7. 認(rèn)證結(jié)果被 SecurityContext 存儲,用于后續(xù)的授權(quán)判斷

應(yīng)用場景

AuthenticationManager 適用于各種需要身份認(rèn)證的場景:

  1. 表單登錄認(rèn)證:處理用戶名 / 密碼登錄
  2. API 認(rèn)證:驗(yàn)證 API 密鑰或令牌
  3. 多因素認(rèn)證:結(jié)合多種認(rèn)證方式
  4. 第三方登錄:如 OAuth2、OpenID Connect 等
  5. 自定義認(rèn)證:實(shí)現(xiàn)特定業(yè)務(wù)需求的認(rèn)證邏輯

實(shí)戰(zhàn)示例(Spring Boot 3.4.3)

下面我們將通過一個(gè)完整示例展示如何在 Spring Boot 3.4.3 中配置和使用 AuthenticationManager

1. 添加依賴

首先在 pom.xml 中添加必要依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 其他依賴 -->
</dependencies>

2. 配置 SecurityConfig

創(chuàng)建 Security 配置類,配置 AuthenticationManager 和安全規(guī)則:

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final UserDetailsService userDetailsService;

    public SecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    // 配置 AuthenticationProvider
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    // 配置 PasswordEncoder
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 配置 AuthenticationManager
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    // 配置安全過濾鏈
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .defaultSuccessUrl("/api/home", true)
                .permitAll()
            )
            .logout(logout -> logout.permitAll());
            
        // 注冊自定義的 AuthenticationProvider
        http.authenticationProvider(authenticationProvider());
        
        return http.build();
    }
}

3. 實(shí)現(xiàn) UserDetailsService

創(chuàng)建自定義的 UserDetailsService 實(shí)現(xiàn),用于加載用戶信息:

package com.example.demo.service;

import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 在實(shí)際應(yīng)用中,這里應(yīng)該從數(shù)據(jù)庫或其他數(shù)據(jù)源加載用戶信息
        if ("user".equals(username)) {
            return User.withUsername("user")
                    .password("$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") // 密碼是 "password"
                    .roles("USER")
                    .build();
        } else if ("admin".equals(username)) {
            return User.withUsername("admin")
                    .password("$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") // 密碼是 "password"
                    .roles("ADMIN", "USER")
                    .build();
        } else {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
    }
}

4. 創(chuàng)建認(rèn)證控制器

創(chuàng)建一個(gè)控制器來演示如何在代碼中使用 AuthenticationManager

package com.example.demo.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    private final AuthenticationManager authenticationManager;

    public AuthController(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @PostMapping("/login")
    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
        // 創(chuàng)建 Authentication 對象
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                loginRequest.getUsername(),
                loginRequest.getPassword()
            )
        );

        // 將認(rèn)證結(jié)果存入 SecurityContext
        SecurityContextHolder.getContext().setAuthentication(authentication);
        
        // 返回認(rèn)證成功的響應(yīng)
        return ResponseEntity.ok(new JwtResponse("dummy-token", 
            authentication.getName(), 
            authentication.getAuthorities().toString()));
    }
    
    // 內(nèi)部類用于接收登錄請求
    public static class LoginRequest {
        private String username;
        private String password;
        
        // getters 和 setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
    
    // 內(nèi)部類用于返回認(rèn)證響應(yīng)
    public static class JwtResponse {
        private String token;
        private String username;
        private String roles;
        
        public JwtResponse(String token, String username, String roles) {
            this.token = token;
            this.username = username;
            this.roles = roles;
        }
        
        // getters
        public String getToken() { return token; }
        public String getUsername() { return username; }
        public String getRoles() { return roles; }
    }
}

5. 測試接口

創(chuàng)建一個(gè)簡單的測試接口來驗(yàn)證認(rèn)證效果:

package com.example.demo.controller;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @GetMapping("/api/public/hello")
    public String publicHello() {
        return "Hello, Public!";
    }

    @GetMapping("/api/home")
    public String home() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        return "Hello, " + auth.getName() + "! You have roles: " + auth.getAuthorities();
    }

    @GetMapping("/api/admin/hello")
    public String adminHello() {
        return "Hello, Admin!";
    }
}

自定義 AuthenticationManager

在某些場景下,我們可能需要自定義 AuthenticationManager 來實(shí)現(xiàn)特定的認(rèn)證邏輯。例如,實(shí)現(xiàn)一個(gè)多因素認(rèn)證:

package com.example.demo.config;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class CustomAuthenticationManager implements AuthenticationManager {

    private final List<AuthenticationProvider> providers;

    public CustomAuthenticationManager(List<AuthenticationProvider> providers) {
        this.providers = providers;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        AuthenticationException lastException = null;
        
        for (AuthenticationProvider provider : providers) {
            if (provider.supports(authentication.getClass())) {
                try {
                    // 調(diào)用 AuthenticationProvider 進(jìn)行認(rèn)證
                    Authentication result = provider.authenticate(authentication);
                    if (result.isAuthenticated()) {
                        // 可以在這里添加額外的認(rèn)證邏輯,如多因素認(rèn)證
                        return result;
                    }
                } catch (AuthenticationException e) {
                    lastException = e;
                }
            }
        }
        
        if (lastException != null) {
            throw lastException;
        }
        
        throw new BadCredentialsException("Authentication failed");
    }
}

總結(jié)

AuthenticationManager 是 Spring Security 認(rèn)證體系的核心組件,負(fù)責(zé)協(xié)調(diào)認(rèn)證過程并委托具體的認(rèn)證邏輯給 AuthenticationProvider 實(shí)現(xiàn)。通過本文的講解和示例,我們了解了:

  1. AuthenticationManager 的基本概念和工作原理
  2. 核心實(shí)現(xiàn)類及其各自的職責(zé)
  3. 在 Spring Boot 3.4.3 中如何配置和使用 AuthenticationManager
  4. 如何通過自定義實(shí)現(xiàn)來滿足特定的認(rèn)證需求

掌握 AuthenticationManager 的使用,將有助于我們更好地理解和擴(kuò)展 Spring Security 的認(rèn)證功能,為應(yīng)用程序提供更安全、更靈活的身份驗(yàn)證機(jī)制。

到此這篇關(guān)于Spring Security AuthenticationManager 接口詳解與實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)springsecurity authenticationmanager接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java線上頻繁FullGC的完整排查流程

    Java線上頻繁FullGC的完整排查流程

    這段文章詳細(xì)介紹了FullGC的的常見觸發(fā)原因原因、排查思路和優(yōu)化方法,涵蓋老年代不足、內(nèi)存泄漏、MetaSpace元空間滿等方面,并提供了從緊急應(yīng)急到長期優(yōu)化的全面解決方案,需要的朋友可以參考下
    2026-06-06
  • Java?@Scheduled定時(shí)任務(wù)不執(zhí)行解決辦法

    Java?@Scheduled定時(shí)任務(wù)不執(zhí)行解決辦法

    這篇文章主要給大家介紹了關(guān)于Java?@Scheduled定時(shí)任務(wù)不執(zhí)行解決的相關(guān)資料,當(dāng)@Scheduled定時(shí)任務(wù)不執(zhí)行時(shí)可以根據(jù)以下步驟進(jìn)行排查和解決,需要的朋友可以參考下
    2023-10-10
  • springboot配置kafka批量消費(fèi),并發(fā)消費(fèi)方式

    springboot配置kafka批量消費(fèi),并發(fā)消費(fèi)方式

    文章介紹了如何在Spring Boot中配置Kafka進(jìn)行批量消費(fèi),并發(fā)消費(fèi),需要注意的是,并發(fā)量必須小于等于分區(qū)數(shù),否則會(huì)導(dǎo)致線程空閑,文章還總結(jié)了創(chuàng)建Kafka分區(qū)的命令,并鼓勵(lì)讀者分享經(jīng)驗(yàn)
    2024-12-12
  • 用攔截器修改返回response,對特定的返回進(jìn)行修改操作

    用攔截器修改返回response,對特定的返回進(jìn)行修改操作

    這篇文章主要介紹了用攔截器修改返回response,對特定的返回進(jìn)行修改操作。具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java中的WebSocket與實(shí)時(shí)通信詳解

    Java中的WebSocket與實(shí)時(shí)通信詳解

    本文介紹WebSocket的概念、工作原理及Java中實(shí)現(xiàn)WebSocket的技術(shù)手段,包括JavaAPIforWebSocket(JSR356)和SpringWebSocket,通過實(shí)際應(yīng)用場景(如即時(shí)聊天、實(shí)時(shí)通知、在線游戲)進(jìn)行了詳細(xì)分析,展示了WebSocket在現(xiàn)代Web應(yīng)用中的重要性,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Java 使用POI生成帶聯(lián)動(dòng)下拉框的excel表格實(shí)例代碼

    Java 使用POI生成帶聯(lián)動(dòng)下拉框的excel表格實(shí)例代碼

    本文通過實(shí)例代碼給大家分享Java 使用POI生成帶聯(lián)動(dòng)下拉框的excel表格,代碼簡單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-09-09
  • java Long==Long有趣的現(xiàn)象詳解

    java Long==Long有趣的現(xiàn)象詳解

    這篇文章主要給大家介紹了關(guān)于java Long==Long有趣的現(xiàn)象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • 深入解析Java類加載的案例與實(shí)戰(zhàn)教程

    深入解析Java類加載的案例與實(shí)戰(zhàn)教程

    本篇文章主要介紹Tomcat類加載器架構(gòu),以及基于類加載和字節(jié)碼相關(guān)知識,去分析動(dòng)態(tài)代理的原理,對Java類加載相關(guān)知識感興趣的朋友一起看看吧
    2022-05-05
  • 手把手教你如何搭建SpringBoot+Vue前后端分離

    手把手教你如何搭建SpringBoot+Vue前后端分離

    這篇文章主要介紹了手把手教你如何搭建SpringBoot+Vue前后端分離,前后端分離是目前開發(fā)中常用的開發(fā)模式,達(dá)成充分解耦,需要的朋友可以參考下
    2023-03-03
  • Spring Cache和EhCache實(shí)現(xiàn)緩存管理方式

    Spring Cache和EhCache實(shí)現(xiàn)緩存管理方式

    這篇文章主要介紹了Spring Cache和EhCache實(shí)現(xiàn)緩存管理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論

开鲁县| 石楼县| 霞浦县| 惠安县| 浮山县| 平遥县| 漳平市| 兴城市| 汤原县| 朔州市| 寿光市| 靖远县| 麦盖提县| 吉首市| 介休市| 肇庆市| 临沧市| 五莲县| 新建县| 巴南区| 石泉县| 宜宾市| 榆中县| 务川| 黎城县| 门源| 廉江市| 汉源县| 龙川县| 长泰县| 新干县| 衡阳市| 信宜市| 侯马市| 建宁县| 红河县| 大同市| 清远市| 永平县| 肃宁县| 肥西县|