跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring Boot 中的认证与授权实践

Spring Boot 集成 Spring Security 的关键在于分清认证和授权:前者负责确认用户身份,后者负责控制访问范围。文章先给出 Maven 依赖和典型安全配置,再分别说明内存认证与数据库认证的实现方式,后者通过 `UserDetailsService` 从数据库加载用户并映射角色。授权部分以 `hasRole`、`hasAnyAuthority` 和 URL 拦截为主。最后强调生产环境应使用加密密码,并优先采用更符合当前版本的配置方式。

w795471发布于 2026/6/30更新于 2026/7/2211 浏览
Spring Boot 中的认证与授权实践

Spring Boot 中的认证与授权实践

在企业应用里,安全通常不是'后面补一下'的功能。Spring Security 跟 Spring Boot 的结合比较顺手,认证、授权、会话控制这些常见需求基本都能在同一套配置里解决。下面按项目里最常见的落地方式梳理一遍。

Spring Security 做什么

Spring Security 主要处理两件事:认证(Authentication)和授权(Authorization)。前者回答'你是谁',后者回答'你能做什么'。它和 Spring 生态贴得很紧,配置、Bean、过滤器链这些东西都在同一套体系里,比单独接一个安全框架省心得多。

项目里怎么接进去

在 Spring Boot 项目中,先把依赖加上。Web 模块之外,核心就是 spring-boot-starter-security。

<dependencies>
    <!-- Web 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Spring Security 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</>
    

scope
</dependency>
</dependencies>

安全配置这块,新版 Spring Security 更推荐 SecurityFilterChain,不过很多项目里还是能看到 WebSecurityConfigurerAdapter。下面这个写法虽然偏老,但读起来直接,尤其适合先把认证流程跑通。

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;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置内存中的用户信息,密码使用明文编码器(生产环境请更换为 BCrypt)
        auth.inMemoryAuthentication()
            .passwordEncoder(NoOpPasswordEncoder.getInstance())
            .withUser("admin").password("admin123").roles("ADMIN")
            .and()
            .withUser("user").password("user123").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .antMatchers("/").permitAll()
            .and()
            .formLogin().loginPage("/login").permitAll()
            .and()
            .logout().permitAll();
    }
}

这里有个现实取舍:内存认证上手快,适合开发和验证配置;一旦上线,就别继续用明文密码和代码里硬编码用户了,重启丢数据只是表面问题,真正的问题是它根本不该出现在生产里。

认证怎么做

内存认证

这是最省事的方式。用户名、密码、角色都写在配置里,启动就能用。调接口、看登录页、验证拦截规则时很方便,但它不负责持久化,也不适合保存真实用户信息。

数据库认证

生产环境里更常见的是把用户信息放到数据库,再通过 UserDetailsService 去加载。

先补上依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

实体类可以先简单一点:

import javax.persistence.*;

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String role;
    // Getter 和 Setter 省略
}

然后自己实现 UserDetailsService,把数据库里的用户映射成 Spring Security 能识别的对象:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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;
import java.util.List;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在:" + username);
        }
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_" + user.getRole()));
        return org.springframework.security.core.userdetails.User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                .authorities(authorities)
                .build();
    }
}

配置里把这个 Service 接上就行:

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
}

这类实现没什么花活,重点在于数据库里存的密码必须是加密后的值。Spring Security 不关心你怎么存,它只关心拿到的密码能不能和登录时输入的内容对上。

授权怎么控

Spring Security 最常用的是基于角色的访问控制,也就是 RBAC。

  • 角色控制:hasRole("ADMIN") 这类写法,适合页面、接口按身份分组。
  • 权限控制:hasAnyAuthority("READ", "WRITE"),粒度更细,适合接口级别的操作限制。

在 HttpSecurity 里通常是按 URL 做拦截:公开接口放开,管理接口收紧。这个思路很朴素,但好维护。规则写得越直白,后面排查越省时间。

常见业务入口

实际项目里,安全模块一般会接登录、登出、注册这些入口。控制器通常不会承担太多安全逻辑,更多是页面跳转和表单提交。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class SecurityController {
    @GetMapping("/")
    public String index() { return "index"; }

    @GetMapping("/login")
    public String login() { return "login"; }

    @PostMapping("/register")
    public String registerUser(String username, String password, String role) {
        // 保存用户逻辑
        return "redirect:/login";
    }
}

如果前端用的是 Thymeleaf,登录表单提交到 /login,登出走 /logout 就够了。具体页面怎么跳,Spring Security 会接管大部分流程,不用自己再手写一套重定向逻辑。

结论

Spring Boot 接 Spring Security,核心不是记配置项,而是先把认证和授权这两条线分清楚。开发阶段用内存认证能快速验证流程,真正上线还是要切到数据库认证,并把密码加密、角色映射和 URL 拦截规则一起理顺。WebSecurityConfigurerAdapter 在老项目里还能见到,新项目更建议直接按当前版本的配置方式来写,少踩兼容性坑。

目录

  1. Spring Boot 中的认证与授权实践
  2. Spring Security 做什么
  3. 项目里怎么接进去
  4. 认证怎么做
  5. 内存认证
  6. 数据库认证
  7. 授权怎么控
  8. 常见业务入口
  9. 结论
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 免费 Trae 编辑器实测:i18n 任务排队千名,AI 编程效率与坑点分析
  • MySQL 基础(3):数据库与表操作
  • Spring Boot 4.0 新特性详解:基线升级、Web 生态与 API 治理
  • Windows 本地部署闲鱼 AI 自动回复系统实战指南
  • 使用 AI 生成个性化头像的完整技术指南
  • 前端监控:别等用户告诉你应用崩了
  • 基于本地知识库的私有 GPT 助手定制教程
  • MCP 开发工具:npx 与 uvx 安装使用指南
  • 科学机器学习中的物理信息神经网络:现状与展望
  • AMD 显卡部署 llama.cpp 性能优化方案
  • 文心一言与通义千问大模型能力对比评测
  • llama.cpp:基于 C/C++ 的本地大语言模型推理框架
  • GitHub Copilot 提升开发效率实战指南
  • Git Bash 安装与基础使用指南
  • lwIP 实战解析:基于 CGI 与 SSI 的嵌入式 WebServer 开发
  • Java Compiler API 核心原理与应用场景
  • 基于 Open-AutoGLM 的梦幻西游网页版自动化任务实现
  • AI 编程工具 Codex 全面上手指南
  • MySQL 动态分区管理:自动化与优化实践
  • JDK8 至 JDK25 全版本特性深度解析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online