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

Spring Security 框架最佳實(shí)踐

 更新時(shí)間:2025年11月21日 10:34:44   作者:海馬  
Spring Security 是一個(gè)功能強(qiáng)大、高度可定制的身份驗(yàn)證(Authentication)和訪問控制(Authorization)框架,是保護(hù)基于 Spring 的應(yīng)用的事實(shí)標(biāo)準(zhǔn),本文給大家介紹Spring Security框架最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧

一、什么是 Spring Security?

Spring Security 是一個(gè)功能強(qiáng)大、高度可定制的身份驗(yàn)證(Authentication)和訪問控制(Authorization)框架,是保護(hù)基于 Spring 的應(yīng)用的事實(shí)標(biāo)準(zhǔn)。

? 核心功能:

  • 用戶登錄認(rèn)證(Authentication)
  • 權(quán)限控制、角色控制(Authorization)
  • 防止 CSRF、會(huì)話固定、點(diǎn)擊劫持等攻擊
  • 支持多種登錄方式:表單登錄、HTTP Basic、OAuth2、JWT、LDAP 等
  • 與 Spring Boot 無縫集成

二、Spring Security 核心概念

1.Authentication(認(rèn)證)

  • 代表“當(dāng)前用戶是誰”,包含用戶名、密碼、權(quán)限等。
  • 由 AuthenticationManager 管理認(rèn)證過程。

2.UserDetails&UserDetailsService

  • UserDetails:封裝用戶信息(用戶名、密碼、權(quán)限、是否鎖定等)
  • UserDetailsService:根據(jù)用戶名加載 UserDetails
@Override
public UserDetails loadUserByUsername(String username) {
    // 從數(shù)據(jù)庫查用戶 → 返回 UserDetails(含加密密碼 + 權(quán)限)
}

3.PasswordEncoder

  • 用于加密密碼和比對密碼。
  • 永遠(yuǎn)不要存儲(chǔ)明文密碼!
  • 常用實(shí)現(xiàn):BCryptPasswordEncoderSCryptPasswordEncoderPbkdf2PasswordEncoder
// 注冊時(shí):
user.setPassword(passwordEncoder.encode(rawPassword));
// 登錄時(shí)(框架自動(dòng)調(diào)用):
passwordEncoder.matches(rawPassword, encodedPassword); // true/false

4.GrantedAuthority

  • 代表一個(gè)權(quán)限,如 "ROLE_ADMIN"、"user:delete"。
  • 通常以 ROLE_ 開頭表示角色,其它表示具體權(quán)限。

5.SecurityContext&SecurityContextHolder

  • 存儲(chǔ)當(dāng)前登錄用戶的信息(Authentication 對象)。
  • 可在任何地方獲取當(dāng)前用戶:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();

三、Spring Security 工作流程(認(rèn)證過程)

sequenceDiagram
    participant User
    participant Filter as FilterChain (Spring Security)
    participant Provider as AuthenticationProvider
    participant Service as UserDetailsService
    participant Encoder as PasswordEncoder
    User->>Filter: 提交用戶名/密碼
    Filter->>Provider: 調(diào)用 authenticate()
    Provider->>Service: loadUserByUsername(username)
    Service-->>Provider: 返回 UserDetails(含加密密碼)
    Provider->>Encoder: matches(輸入密碼, 數(shù)據(jù)庫加密密碼)
    alt 匹配成功
        Encoder-->>Provider: true
        Provider-->>Filter: 返回認(rèn)證成功 Authentication
        Filter->>User: 登錄成功,跳轉(zhuǎn)
    else 匹配失敗
        Encoder-->>Provider: false
        Provider-->>Filter: 拋出異常
        Filter->>User: 登錄失敗
    end

四、常用配置方式(Spring Boot)

1. 引入依賴(Maven)

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

2. 基礎(chǔ)配置類(啟用 Web 安全)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/login", "/register", "/css/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")           // 自定義登錄頁
                .defaultSuccessUrl("/home")    // 登錄成功跳轉(zhuǎn)
                .permitAll()
            )
            .logout(logout -> logout
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            );
        return http.build();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // 推薦使用 BCrypt
    }
}

3. 自定義 UserDetailsService

@Component
public class MyUserServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userMapper.findUserByName(username);
        if (user == null) throw new UsernameNotFoundException("用戶不存在");
        // ? 直接返回?cái)?shù)據(jù)庫中的加密密碼(注冊時(shí)已加密存儲(chǔ)?。?
        return User.builder()
            .username(user.getUsername())
            .password(user.getSupwd()) // ← 不要再 encode!
            .roles("USER") // 或者 .authorities(getAuthorities())
            .build();
    }
}

五、權(quán)限控制(授權(quán) Authorization)

1. 方法級(jí)別權(quán)限(推薦)

@Service
public class ArticleService {
    @PreAuthorize("hasRole('ADMIN')") // 需要 ADMIN 角色
    public void deleteArticle(Long id) {
        // ...
    }
    @PreAuthorize("hasAuthority('article:edit')") // 需要具體權(quán)限
    public void editArticle(Article article) {
        // ...
    }
    @PostAuthorize("returnObject.owner == authentication.name")
    public Article getArticle(Long id) {
        // 返回后檢查:只有文章主人才能看
    }
}

?? 要啟用方法級(jí)權(quán)限,需在配置類加:@EnableMethodSecurity

@Configuration
@EnableWebSecurity
@EnableMethodSecurity // ← 啟用 @PreAuthorize 等注解
public class SecurityConfig { ... }

2. 頁面級(jí)別權(quán)限(Thymeleaf)

<!-- 只有 ADMIN 能看到 -->
<div sec:authorize="hasRole('ADMIN')">
    <a href="/admin" rel="external nofollow" >管理后臺(tái)</a>
</div>
<!-- 顯示當(dāng)前用戶名 -->
<span sec:authentication="name"></span>

需引入:

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>

六、常見自定義擴(kuò)展

1. 自定義登錄成功/失敗處理器

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, 
                                        HttpServletResponse response, 
                                        Authentication authentication) throws IOException {
        response.sendRedirect("/home?loginSuccess");
    }
}

在配置中使用:

.formLogin(form -> form
    .successHandler(mySuccessHandler)
    .failureHandler(myFailureHandler)
)

2. 自定義權(quán)限異常處理

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
        response.sendRedirect("/403");
    }
}

配置:

.exceptionHandling(ex -> ex
    .accessDeniedHandler(myAccessDeniedHandler)
)

七、與 JWT / 前后端分離集成(簡要)

如果你是前后端分離項(xiàng)目(如 Vue + Spring Boot),通常不用 Session,改用 JWT:

  1. 用戶 POST /login 提交用戶名密碼
  2. 后端驗(yàn)證成功 → 生成 JWT Token 返回
  3. 前端后續(xù)請求在 Header 中攜帶 Authorization: Bearer <token>
  4. 后端用 Filter 解析 Token → 設(shè)置 SecurityContext

?? 此時(shí) UserDetailsService 依然有用 —— 用于從 Token 中的用戶名加載用戶權(quán)限!

八、最佳實(shí)踐 & 注意事項(xiàng)

項(xiàng)目建議
密碼存儲(chǔ)必須加密(BCrypt 最常用)
密碼比對交給 Spring Security,不要手動(dòng)比對
權(quán)限設(shè)計(jì)角色(ROLE_) + 細(xì)粒度權(quán)限(user:delete)結(jié)合
登錄頁可自定義,但路徑要 permitAll
CSRF表單登錄默認(rèn)開啟,JWT 項(xiàng)目可關(guān)閉
調(diào)試可臨時(shí) .authorizeHttpRequests(authz -> authz.anyRequest().permitAll()) 放行所有

? 總結(jié)一句話:

Spring Security = 認(rèn)證(你是誰)+ 授權(quán)(你能干什么)+ 安全防護(hù),你只需要提供“用戶數(shù)據(jù)”和“權(quán)限規(guī)則”,框架自動(dòng)完成驗(yàn)證和攔截。

?? 學(xué)習(xí)路徑建議:

  1. 先跑通表單登錄 + 自定義 UserDetailsService
  2. 學(xué)會(huì)配置 URL 權(quán)限控制
  3. 掌握方法級(jí)權(quán)限 @PreAuthorize
  4. 學(xué)習(xí)自定義處理器(登錄成功/失敗、無權(quán)限)
  5. 進(jìn)階:JWT、OAuth2、方法權(quán)限表達(dá)式、動(dòng)態(tài)權(quán)限

?? 送你一個(gè)完整可運(yùn)行的最小示例結(jié)構(gòu):

src/
├── controller/
│   └── LoginController.java       // 登錄頁、首頁
├── service/
│   └── MyUserServiceImpl.java     // loadUserByUsername
├── config/
│   └── SecurityConfig.java        // 權(quán)限配置 + PasswordEncoder
└── entity/
    └── User.java                  // 用戶實(shí)體(含加密密碼字段)

到此這篇關(guān)于Spring Security 框架的文章就介紹到這了,更多相關(guān)spring security 框架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中String的split切割字符串方法實(shí)例及擴(kuò)展

    Java中String的split切割字符串方法實(shí)例及擴(kuò)展

    最近在項(xiàng)目中遇到一個(gè)小問題,一個(gè)字符串分割成一個(gè)數(shù)組,下面這篇文章主要給大家介紹了關(guān)于Java中String的split切割字符串方法的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • java實(shí)現(xiàn)簡單登錄界面的實(shí)戰(zhàn)過程

    java實(shí)現(xiàn)簡單登錄界面的實(shí)戰(zhàn)過程

    學(xué)習(xí)JAVA的過程當(dāng)中,登陸界面是多數(shù)人第一個(gè)實(shí)現(xiàn)的小程序,下面這篇文章主要給大家介紹了關(guān)于利用java實(shí)現(xiàn)簡單登錄界面的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析

    JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析

    這篇文章主要介紹了JavaWeb中struts2文件上傳下載功能的實(shí)現(xiàn),在Web應(yīng)用系統(tǒng)開發(fā)中,文件上傳和下載功能是非常常用的功能,需要的朋友可以參考下
    2016-05-05
  • 如何解決IDEA使用Tomcat控制臺(tái)中文出現(xiàn)亂碼問題

    如何解決IDEA使用Tomcat控制臺(tái)中文出現(xiàn)亂碼問題

    這篇文章主要介紹了如何解決IDEA使用Tomcat控制臺(tái)中文出現(xiàn)亂碼問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 這一次搞懂Spring的Bean實(shí)例化原理操作

    這一次搞懂Spring的Bean實(shí)例化原理操作

    這篇文章主要介紹了這一次搞懂Spring的Bean實(shí)例化原理操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • SpringBoot中的ApplicationRunner與CommandLineRunner問題

    SpringBoot中的ApplicationRunner與CommandLineRunner問題

    這篇文章主要介紹了SpringBoot中的ApplicationRunner與CommandLineRunner問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之KMP算法

    Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之KMP算法

    在很多地方也都經(jīng)常看到講解KMP算法的文章,看久了好像也知道是怎么一回事,但總感覺有些地方自己還是沒有完全懂明白。這兩天花了點(diǎn)時(shí)間總結(jié)一下,有點(diǎn)小體會(huì),我希望可以通過我自己的語言來把這個(gè)算法的一些細(xì)節(jié)梳理清楚,也算是考驗(yàn)一下自己有真正理解這個(gè)算法
    2022-02-02
  • Java ConcurrentHashMap鎖分段機(jī)制使用及代碼實(shí)例

    Java ConcurrentHashMap鎖分段機(jī)制使用及代碼實(shí)例

    ConcurrentHashMap是Java中的一種線程安全的哈希表,通過鎖分段機(jī)制提高了并發(fā)性能,在Java 8中,ConcurrentHashMap引入了CAS操作和更復(fù)雜的節(jié)點(diǎn)繼承結(jié)構(gòu),進(jìn)一步優(yōu)化了并發(fā)操作
    2025-01-01
  • IDEA中osgi的開發(fā)應(yīng)用指南詳解

    IDEA中osgi的開發(fā)應(yīng)用指南詳解

    這篇文章主要介紹了IDEA中osgi的開發(fā)應(yīng)用指南詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • Java實(shí)現(xiàn)微信掃碼登入的實(shí)例代碼

    Java實(shí)現(xiàn)微信掃碼登入的實(shí)例代碼

    這篇文章主要介紹了java實(shí)現(xiàn)微信掃碼登入功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06

最新評論

张家界市| 安塞县| 清涧县| 兰坪| 旺苍县| 微山县| 子洲县| 霍林郭勒市| 衡阳市| 庆安县| 竹山县| 桑日县| 昆山市| 汕头市| 江孜县| 内丘县| 南京市| 凤台县| 泰宁县| 枞阳县| 台州市| 望奎县| 新民市| 深泽县| 黑山县| 西乌珠穆沁旗| 郴州市| 永州市| 商河县| 雷山县| 改则县| 红河县| 临洮县| 辰溪县| 龙岩市| 土默特右旗| 铅山县| 运城市| 德钦县| 濮阳市| 黔南|