Spring Boot的安全性:基本认证与JWT认证!

举报
bug菌 发表于 2025/06/05 11:55:59 2025/06/05
【摘要】 🏆 本文精选收录于《滚雪球学SpringBoot》专栏,专为零基础学习者量身打造。从Spring基础到项目实战,手把手带你掌握核心技术,助力你快速提升,迈向职场巅峰,开启财富自由之路🚀!无论你是刚入门的小白,还是已有基础的开发者,都能在这里找到适合自己的学习路径!    🌟 关注、收藏、订阅,持续更新中!和我们一起高速成长,突破自我!💡

🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

前言 🤔

在现代Web应用中,安全性是一个至关重要的方面,尤其是当我们处理用户数据和身份验证时。Spring Security是一个强大的框架,能够为Spring Boot应用提供全面的安全功能,包括身份验证(Authentication)和授权(Authorization)。在这篇文章中,我们将探索两种常见的身份验证方式:基本认证(Basic Authentication)JWT认证(JSON Web Token),并学习如何在Spring Boot应用中实现它们。🎯

目录 📋

  1. Spring Boot安全性基础 ⚙️
  2. 基本认证(Basic Authentication) 🔑
  3. JWT认证(JSON Web Token) 🔒
  4. 如何选择适合的认证方式 ⚖️

1. Spring Boot安全性基础 ⚙️

Spring Boot默认集成了Spring Security,并且在应用启动时自动启用基本的安全功能。Spring Security为应用提供了一些默认的配置,如:

  • 基本认证。
  • 内存中的用户存储(默认用户名user,密码自动生成)。
  • 请求保护(所有请求默认需要身份验证)。

Spring Security提供了丰富的认证机制,包括表单登录、HTTP基本认证、JWT认证等。今天,我们将主要关注基本认证JWT认证两种方式。

1.1 添加Spring Security依赖

首先,我们需要在pom.xml中添加Spring Security的依赖。如果你使用Spring Boot创建项目,Spring Security通常已经作为默认依赖。

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

2. 基本认证(Basic Authentication) 🔑

基本认证(Basic Authentication)是一种简单的认证方式,客户端在HTTP请求中通过Authorization头部传递用户名和密码。其格式为:Authorization: Basic <base64(username:password)>

2.1 基本认证的工作原理

  1. 客户端发送请求,包含Authorization头部,格式为Basic <base64(username:password)>
  2. Spring Security解析该头部,进行身份验证。
  3. 如果用户名和密码正确,服务器返回对应的资源。如果认证失败,返回HTTP 401 Unauthorized状态。

2.2 配置基本认证

Spring Boot与Spring Security默认启用了基本认证。你可以通过配置application.properties来指定默认的用户名和密码,或者通过自定义配置来进行修改。

application.properties中配置默认用户:

spring.security.user.name=user
spring.security.user.password=password

2.3 自定义基本认证

如果你需要自定义更多的认证行为,可以通过扩展WebSecurityConfigurerAdapter类来实现:

SecurityConfig.java

package com.example.demo;

import org.springframework.context.annotation.Bean;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()  // 保护所有请求
            .and()
            .httpBasic();  // 启用基本认证
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();  // 密码加密
    }
}

在这个配置中,httpBasic()方法启用了基本认证,并通过authorizeRequests()配置了请求的认证策略。通过这种方式,所有请求都需要进行身份验证。

3. JWT认证(JSON Web Token) 🔒

JWT(JSON Web Token)是一种轻量级的认证方式,通常用于无状态的认证系统。JWT将认证信息封装在一个token中,每次请求时,客户端会将token包含在Authorization头部中进行身份验证。

JWT的主要优势是:

  • 无状态:服务器不需要存储会话信息,减少了服务器负担。
  • 自包含:JWT包含了用户的认证信息,可以在token中附带额外的数据(例如用户角色、权限等)。

3.1 JWT的工作原理

  1. 用户第一次登录时,服务器验证用户的凭据(例如用户名和密码),并生成一个JWT token。
  2. 客户端收到token后,将其存储(通常存在浏览器的localStorage或sessionStorage中)。
  3. 每次发起请求时,客户端会将token放入Authorization头部中,格式为Bearer <token>
  4. 服务器验证token的有效性,并根据token中的信息执行相应的操作。

3.2 配置JWT认证

配置JWT认证需要三个主要步骤:

  • 生成JWT Token:用户登录后,服务器生成并返回token。
  • 验证JWT Token:每次请求时,服务器验证客户端提供的token是否合法。
  • 保护端点:根据token中的权限信息保护API端点。

步骤 1:生成JWT Token

我们首先需要创建一个JWT工具类,用于生成和解析token。

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtTokenUtil {

    private String secretKey = "secret";  // 密钥

    public String generateToken(String username) {
        return Jwts.builder()
            .setSubject(username)
            .setExpiration(new Date(System.currentTimeMillis() + 86400000))  // 24小时过期
            .signWith(SignatureAlgorithm.HS512, secretKey)
            .compact();
    }

    public String getUsernameFromToken(String token) {
        return Jwts.parser()
            .setSigningKey(secretKey)
            .parseClaimsJws(token)
            .getBody()
            .getSubject();
    }

    public boolean isTokenExpired(String token) {
        Date expiration = Jwts.parser()
            .setSigningKey(secretKey)
            .parseClaimsJws(token)
            .getBody()
            .getExpiration();
        return expiration.before(new Date());
    }
}

步骤 2:JWT过滤器

创建一个JWT过滤器(JwtAuthenticationFilter)来验证请求中的JWT token。

import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import java.io.IOException;

public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private JwtTokenUtil jwtTokenUtil;

    public JwtAuthenticationFilter(JwtTokenUtil jwtTokenUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String token = request.getHeader("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);  // 去掉"Bearer "部分
            String username = jwtTokenUtil.getUsernameFromToken(token);

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                if (!jwtTokenUtil.isTokenExpired(token)) {
                    UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}

步骤 3:配置Spring Security集成JWT

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
                .antMatchers("/login", "/signup").permitAll()  // 不需要认证的端点
                .anyRequest().authenticated();  // 其他请求需要身份验证
    }

    @Bean
    public JwtTokenUtil jwtTokenUtil() {
        return new JwtTokenUtil();
    }
}

4. 如何选择适合的认证方式 ⚖️

4.1 基本认证

  • 适用场景:适合小型应用,或者用于API测试和原型开发。
  • 优点:实现简单,配置容易。
  • 缺点:每次请求都需要传输用户名和密码,存在一定的安全风险。

4.2 JWT认证

  • 适用场景:适合构建无状态、分布式和微服务架构的应用。
  • 优点:无需存储会话,token自包含且有过期时间,适用于高并发环境。
  • 缺点:需要额外的实现步骤(生成token和验证token)。

总结 🌟

通过Spring Security,Spring Boot可以轻松实现两种常见的认证方式:基本认证JWT认证。基本认证实现简单,适用于小型应用和开发阶段;而JWT认证适合无状态应用、高并发和微服务架构,通过token管理用户的认证信息更加高效且安全。

选择认证方式时,需根据应用的需求进行权衡。对于简单应用,基本认证可能足够;而对于复杂的分布式系统,JWT认证则提供了更多的优势。

🧧福利赠与你🧧

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」专栏(全网一个名),bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

✨️ Who am I?

我是bug菌(全网一个名),CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云多年度十佳博主/价值贡献奖,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;更多精彩福利点击这里;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。

-End-

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。