程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Python 基础

    • Python基础
  • Python 进阶

    • 装饰器与生成器
    • 异常处理
    • 标准库精讲
    • 模块与包
    • pip包管理工具
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
前端 (opens new window)
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Python 基础

    • Python基础
  • Python 进阶

    • 装饰器与生成器
    • 异常处理
    • 标准库精讲
    • 模块与包
    • pip包管理工具
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
前端 (opens new window)
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • SpringSecurity

    • Spring Security是什么
    • 认证与授权的基本概念
    • Spring Security 的默认配置
    • SpringSecurity的默认登录页
    • Spring Security 的 Filter 机制
    • HttpSecurity 与自定义登录页面
      • 1. HttpSecurity 是什么?
      • 2. 基本结构与配置方法
      • 3. 重要配置参数说明
      • 4. 自定义用户名和密码
      • 5. 自定义登录页面配置
      • 6. 自定义登录页面的前端实现
      • 7. 登录逻辑的处理
      • 8. 高级配置与扩展
    • Spring Security 的核心组件与扩展
    • Spring Security 中的用户认证与角色管理
    • Spring Security 的授权机制与安全表达式
    • Security 的 Session 与 Token 管理
    • Spring Security 集成第三方登录
    • Spring Security 集成 QQ 登录与 JWT 认证
    • Spring Security 登录认证源码
    • Spring Security - JWT认证实战
    • Spring Security - JWT授权实战
    • Spring Security 异常处理与自定义逻辑
  • SpringSecurity
  • SpringSecurity
scholar
2024-08-20
目录

HttpSecurity 与自定义登录页面

# HttpSecurity 与自定义登录页面

前言

Spring Security 默认提供了基础的认证和授权机制,但在实际项目中,通常需要自定义认证规则和登录页面。为了更有条理地学习,本节将详细介绍如何通过 HttpSecurity 配置认证规则、路径访问控制以及如何自定义登录页面。

# 1. HttpSecurity 是什么?

HttpSecurity 是 Spring Security 提供的配置类,用于定义基于 HTTP 请求的安全控制。它提供了丰富的 API,可以配置认证、授权、CSRF 防护、会话管理等。通过这个类,你可以详细指定哪些路径需要认证、哪些路径可以匿名访问,甚至可以自定义登录和注销行为。

# 2. 基本结构与配置方法

HttpSecurity 的配置通常在继承自 WebSecurityConfigurerAdapter 的类中进行,并通过重写 configure(HttpSecurity http) 方法来实现。

注意事项

在 Spring Boot 2.7 和 Spring Security 5.7 之后,WebSecurityConfigurerAdapter 已经被标记为**过时(Deprecated)**并被移除。这是因为 Spring Security 推出了基于 SecurityFilterChain 和 SecurityConfigurer 的配置方式,这种方式更具灵活性和模块化。

代码示例:基本的 HttpSecurity 配置

import org.springframework.context.annotation.Configuration;
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;

@Configuration
@EnableWebSecurity  // 启用 Spring Security
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()  // 开始定义路径访问规则
                .antMatchers("/admin/**").hasRole("ADMIN")  // /admin/** 需要 ADMIN 角色
                .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")  // /user/** 需要 USER 或 ADMIN 角色
                .antMatchers("/", "/home", "/public/**").permitAll()  // 公开访问的路径
                .anyRequest().authenticated()  // 其他所有请求都需要认证
            .and()
            .formLogin()  // 启用表单登录
                .loginPage("/login")  // 自定义登录页面路径
                .loginProcessingUrl("/perform_login")  // 表单提交路径,Spring Security 自动处理
                .defaultSuccessUrl("/dashboard", true)  // 登录成功后的默认跳转路径
                .failureUrl("/login?error=true")  // 登录失败后的跳转路径
                .usernameParameter("username")  // 表单用户名字段名称
                .passwordParameter("password")  // 表单密码字段名称
                .permitAll()  // 允许所有用户访问登录页面
            .and()
            .logout()  // 启用注销功能
                .logoutUrl("/logout")  // 自定义注销路径
                .logoutSuccessUrl("/login?logout=true")  // 注销成功后的跳转路径
                .permitAll();  // 允许所有用户访问注销路径
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 3. 重要配置参数说明

  • authorizeRequests():配置路径访问权限。常见的用法包括:

    • antMatchers(String... paths):用于匹配指定的 URL 路径,并配置访问规则。
      • hasRole(String role):要求特定角色访问(默认添加 ROLE_ 前缀,如 hasRole("ADMIN") 实际匹配 ROLE_ADMIN)。
      • permitAll():允许所有用户(包括未登录用户)访问。
      • authenticated():要求用户必须登录才能访问。
  • formLogin():配置表单登录行为。常用配置参数:

    • loginPage(String loginPageUrl):指定自定义登录页面路径。当用户访问受保护资源且未登录时,Spring Security 会自动重定向到该路径。
    • loginProcessingUrl(String loginProcessingUrl):指定表单提交的路径。前端表单的 action 属性应设置为此路径,Spring Security 会自动处理登录逻辑。
    • defaultSuccessUrl(String defaultUrl, boolean alwaysUse):指定登录成功后的跳转路径。alwaysUse 参数为 true 时,无论用户之前访问了什么页面,登录成功后都跳转到该路径。
    • failureUrl(String failureUrl):指定登录失败后的跳转路径。前端页面可根据 URL 参数显示登录失败提示。
    • usernameParameter(String usernameParameter) 和 passwordParameter(String passwordParameter):指定表单中用户名和密码的字段名称,默认为 username 和 password。
  • logout():配置注销功能。常用配置参数:

    • logoutUrl(String logoutUrl):指定自定义的注销路径,默认路径为 /logout。
    • logoutSuccessUrl(String logoutSuccessUrl):指定注销成功后的跳转路径。

# 4. 自定义用户名和密码

在默认配置下,Spring Security 会随机生成一个默认用户(user)和密码。如果你需要自定义用户名和密码,可以通过以下方式实现:

代码示例:使用 inMemoryAuthentication() 配置自定义用户

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()  // 使用内存中的用户信息
            .withUser("admin")  // 自定义用户名为 "admin"
            .password("{noop}password")  // 自定义密码为 "password",{noop} 表示不进行加密
            .roles("ADMIN")  // 赋予 ADMIN 角色
            .and()
            .withUser("user")  // 设置另一个用户,用户名为 "user"
            .password("{noop}password")  // 设置密码为 "password"
            .roles("USER");  // 赋予 USER 角色
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
                .antMatchers("/", "/home", "/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

关键点说明:

  • inMemoryAuthentication():使用内存中的用户数据源进行配置。
  • withUser("username"):定义用户名。
  • password("{noop}password"):设置用户密码。{noop} 表示不进行加密,在实际生产环境中应使用加密方式(如 BCryptPasswordEncoder)。
  • roles("ROLE_NAME"):为用户分配角色,Spring Security 默认在角色前面添加 ROLE_ 前缀。

# 5. 自定义登录页面配置

在实际项目中,通常需要自定义登录页面来满足设计需求。通过配置 HttpSecurity,你可以轻松实现自定义登录页面。

代码示例:自定义登录页面配置

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/login", "/register", "/public/**").permitAll()  // 允许所有用户访问登录页面、注册页面和公开路径
            .anyRequest().authenticated()  // 其他所有请求都需要认证
        .and()
        .formLogin()
            .loginPage("/login")  // 自定义登录页面路径
            .loginProcessingUrl("/perform_login")  // 表单提交路径
            .defaultSuccessUrl("/home", true)  // 登录成功后的跳转路径
            .failureUrl("/login?error=true")  // 登录失败后的跳转路径
            .usernameParameter("username")  // 表单用户名字段名称
            .passwordParameter("password")  // 表单密码字段名称
            .permitAll()  // 允许所有用户访问登录页面和相关路径
        .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout=true")
            .permitAll();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 6. 自定义登录页面的前端实现

在前端(如 Vue 项目中),你需要确保表单字段名和路径与后端配置一致。

HTML 表单示例(Vue 模板):

<template>
  <div class="login-container">
    <form action="/perform_login" method="POST">
      <div>
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" required />
      </div>
      <div>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password" required />
      </div>
      <button type="submit">登录</button>
      <div v-if="$route.query.error === 'true'">登录失败,请检查用户名或密码。</div>
    </form>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

注意:

  • 表单的 action 属性应设置为后端配置的 loginProcessingUrl(如 /perform_login)。
  • 表单字段名称应与后端配置相匹配。

# 7. 登录逻辑的处理

注意在当前默认配置下,Spring Security 是通过以下步骤进行用户认证的:

  1. 使用内存中定义的用户信息:在前面的默认配置中,我们通过 inMemoryAuthentication() 定义了一个用户名为 username 的用户和密码为 password 的简单用户信息。Spring Security 默认使用这个信息进行认证。
  2. 登录逻辑的处理:
    • 当用户提交登录表单时,Spring Security 的 UsernamePasswordAuthenticationFilter 过滤器会自动捕获表单中的 username 和 password 字段。
    • 然后,Spring Security 会将表单中的用户名和密码与内存中定义的用户信息进行比对。
    • 如果用户名和密码匹配,认证成功,Spring Security 会将认证信息存储在 SecurityContext 中,并跳转到配置的成功页面。
    • 如果匹配失败,用户将被重定向到登录失败页面。
  3. 验证的用户信息来源:目前的配置是通过内存中配置的用户信息进行验证,并没有与数据库连接。因此,Spring Security 校验的仍然是我们在 SecurityConfig 类中硬编码的用户名和密码。

如果需要与数据库关联,可以实现自定义的 UserDetailsService,加载用户信息并进行认证。

# 8. 高级配置与扩展

  • 禁用 CSRF 防护:在 REST API 项目中通常需要禁用 CSRF 防护:

    http.csrf().disable();
    
    1
  • 配置跨域资源共享(CORS):

    http.cors().configurationSource(corsConfigurationSource());
    
    1

总结

通过 HttpSecurity,你可以全面控制 Spring Security 的认证和授权行为。无论是默认配置还是自定义配置,都可以灵活适配项目需求。掌握这些配置后,你可以轻松实现基于角色的权限控制、自定义登录页面以及复杂的路径访问规则。

编辑此页 (opens new window)
上次更新: 2024/12/29, 23:35:48
Spring Security 的 Filter 机制
Spring Security 的核心组件与扩展

← Spring Security 的 Filter 机制 Spring Security 的核心组件与扩展→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式