楼层: 首页/ 软件技术/ Spring Boot 3.5/ Spring Security 入门:登录与放行
12

Spring Security 入门:登录与放行

Spring Security · Filter Chain · JWT

Web 应用谁都能访问?接口裸奔?引入 spring-boot-starter-security 后,默认所有接口都要登录才能访问,还自动给你生成一个登录页和初始密码。它的核心是一条过滤器链:每个请求经过一串过滤器,挨个判断"你是谁、你有权限吗"。

第一个安全应用:加依赖就全拦了

<!-- pom 里加这个,Spring Security 自动生效 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>

启动后访问任意接口,会跳到自带登录页。默认用户名 user,密码在启动日志里打出来(一串 UUID)。这只是演示,下面自己配。

配置放行规则与内存用户(Spring Security 6 写法)

// SecurityFilterChain:用 @Configuration 配一条过滤器链 @Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login", "/public/**").permitAll() // 这些放行 .anyRequest().authenticated() "> 其余都要登录 ) .formLogin(form -> form.defaultSuccessUrl("/")) .csrf(csrf -> csrf.disable()); // 纯后端 API 先关了,前后端分离另说 return http.build(); } @Bean public UserDetailsService users(PasswordEncoder encoder) { // 演示用内存用户;生产换成从数据库读 var admin = User.withUsername("admin") .password(encoder.encode("123456")) .roles("ADMIN").build(); return new InMemoryUserDetailsManager(admin); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); // 密码必须加密存,不能明文 } }

前后端分离:JWT 无状态认证

上面是表单登录(有 Session)。前后端分离 + 微服务,普遍用 JWT:登录成功后端发一个 token,前端以后每个请求带在 Authorization: Bearer xxx 头里,后端过滤器验签,不存 Session。Spring Cloud 那章会在网关统一做这事。

论记住三个坑

① 密码永不明文:用 BCrypt 之类加密存储,登录时比对哈希。② CSRF:纯 JSON API 可以关,带 Cookie 的表单必须开。③ 默认拦截一切:忘了 permitAll 登录页就打不开,别慌,是配错了。

章末面试 · Spring Security(3 题)

1.(概念题)Spring Security 的核心机制是什么?

查看答案

答案:一条 Servlet 过滤器链(SecurityFilterChain),每个请求经过一串过滤器,依次完成认证(你是谁)和授权(你能干啥)。

2.(实践题)为什么数据库里不能存明文密码?

查看答案

答案:数据库一泄露所有账号就裸奔。用 BCryptPasswordEncoder 加盐哈希,即使泄露也不可逆。

3.(概念题)JWT 方案为什么不用 Session?

查看答案

答案:JWT 是无状态的,认证信息自包含在 token 里,服务端不存会话,方便水平扩展和网关统一鉴权;代价是 token 一旦签发,想主动失效要配合黑名单/短过期。