Spring Boot 安全认证与授权:守护应用的“铁拳”!

举报
bug菌 发表于 2025/09/16 11:04:13 2025/09/16
【摘要】 🏆本文收录于「滚雪球学SpringBoot」专栏(全网一个名),手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8 前言 🔐在现代 Web 应用开发中,安全性已经成为了一个不容忽视的关...

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

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

前言 🔐

在现代 Web 应用开发中,安全性已经成为了一个不容忽视的关键因素。从用户身份验证到权限控制,如何保证系统在提供功能的同时,也能确保数据的安全性和隐私保护,已经成为开发者面临的重要课题。🚀

Spring Boot 在构建高效、安全的 Web 应用时,提供了强大的安全框架——Spring Security。Spring Security 不仅可以帮助我们进行常见的身份认证和授权,还支持多种认证机制,如 JWT、OAuth2 和单点登录(SSO)等。在这篇文章中,我们将详细探索如何使用 Spring Security 来实现安全认证与授权,确保你的应用在开放接口和敏感数据的处理时,能够抵御外部的攻击和威胁。

Spring Security 概述 🛡️

1. 什么是 Spring Security?

Spring Security 是一个功能强大的安全框架,专门用来为基于 Spring 的应用提供认证(Authentication)和授权(Authorization)功能。它是 Spring 的一部分,能够无缝集成到 Spring Boot 项目中,提供丰富的安全功能,包括:

  • 认证:验证用户的身份,确保请求是由合法用户发出的。
  • 授权:控制用户访问系统资源的权限,防止未授权用户访问敏感数据或功能。
  • 防止 CSRF 攻击:Spring Security 提供了跨站请求伪造(CSRF)保护,防止恶意脚本的攻击。
  • 防止会话劫持:通过会话管理防止不合法的会话被劫持。

2. Spring Security 的核心组件

Spring Security 提供了几个重要的核心组件,使得安全控制变得更加灵活:

  • AuthenticationManager:管理认证的核心接口,负责认证用户身份。
  • UserDetailsService:用来提供用户的详细信息,比如用户名、密码、角色等。
  • GrantedAuthority:表示用户的权限,它可以是角色或者其他权限标识。
  • SecurityContext:存储当前用户的认证信息。

通过这些组件,Spring Security 允许开发者定制灵活的安全机制。

配置 Spring Security 与表单认证 📝

1. Spring Boot 集成 Spring Security

要在 Spring Boot 项目中启用 Spring Security,只需要在 pom.xml 文件中添加 spring-boot-starter-security 依赖:

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

Spring Boot 会自动为我们配置一个简单的安全认证系统。默认情况下,Spring Security 会启用一个基本的 表单认证,并提供默认的用户名和密码(user 和一个自动生成的密码)。如果你启动应用,尝试访问任何受保护的资源时,你会被要求登录。

2. 自定义表单登录

为了更好地适应实际开发需求,我们常常需要定制登录页面和认证逻辑。在 Spring Security 中,表单认证的配置非常灵活。

配置自定义登录页面

首先,我们需要定义一个自定义的登录页面。在 src/main/resources/templates 中,创建一个 login.html 文件,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
</head>
<body>
    <h2>Login</h2>
    <form action="/login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required /><br><br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required /><br><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>

配置 Spring Security 使用自定义登录页面

接下来,我们通过配置类来告诉 Spring Security 使用我们自定义的登录页面:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll() // 不需要认证的页面
                .anyRequest().authenticated() // 其他页面需要认证
            .and()
            .formLogin()
                .loginPage("/login") // 自定义登录页面
                .permitAll() // 允许所有用户访问登录页面
            .and()
            .logout()
                .permitAll();
    }
}

此时,Spring Security 会将 /login 页面作为登录页面,用户必须通过该页面输入凭证才能访问受保护的资源。通过这种方式,我们实现了简单而灵活的表单认证。

JWT 认证机制与集成 🔑

1. 什么是 JWT?

JWT(JSON Web Token) 是一种开放标准(RFC 7519),它定义了一种简洁的自包含的方式,用于在各方之间安全地传输信息。JWT 广泛应用于认证和授权系统,特别是在现代的分布式系统和单页面应用(SPA)中。

JWT 主要由三部分组成:

  1. Header:包含令牌类型(JWT)和签名算法(如 HMAC SHA256 或 RSA)。
  2. Payload:包含用户的声明(比如用户信息、权限等)。
  3. Signature:用来验证信息是否被篡改。

2. Spring Security 集成 JWT

JWT 认证机制的关键在于:用户首次登录时,系统验证用户身份,并生成一个 JWT 返回给客户端,客户端保存该 JWT,并在后续的请求中通过 HTTP 头部将其发送给服务器,服务器验证 JWT 来判断用户是否已认证。

添加 JWT 依赖

首先,需要在 pom.xml 中添加以下依赖:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.11.2</version>
</dependency>

配置 JWT 生成与解析

接下来,创建一个工具类来生成和解析 JWT:

public class JwtUtil {

    private String secretKey = "mySecretKey";

    // 生成 JWT
    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1小时有效期
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
    }

    // 解析 JWT
    public String extractUsername(String token) {
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }

    // 验证 JWT
    public boolean validateToken(String token, String username) {
        String extractedUsername = extractUsername(token);
        return (extractedUsername.equals(username) && !isTokenExpired(token));
    }

    // 判断 JWT 是否过期
    private boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    // 获取过期时间
    private Date extractExpiration(String token) {
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody()
                .getExpiration();
    }
}

配置 JWT 过滤器

创建一个过滤器,检查每个请求中是否携带了 JWT,并对其进行验证:

public class JwtFilter extends OncePerRequestFilter {

    private JwtUtil jwtUtil;

    public JwtFilter(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected 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);
            if (jwtUtil.validateToken(token, "username")) {
                // Token 验证通过,进行后续操作
                SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("username", null, new ArrayList<>()));
            }
        }
        filterChain.doFilter(request, response);
    }
}

配置 Spring Security 使用 JWT

在 Spring Security 配置类中,添加 JWT 过滤器来对每个请求进行验证:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private JwtFilter jwtFilter;

    @Autowired
    public SecurityConfig(JwtFilter jwtFilter) {
        this.jwtFilter = jwtFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)  // 将 JWT 过滤器添加到认证过滤器链中
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated();
    }
}

通过这种方式,我们实现了基于 JWT 的认证机制,用户登录后将获得一个有效的 JWT,该令牌用于后续的身份验证。

基于角色的访问控制 ⚙️

1. 角色与权限管理

Spring Security 支持基于角色(Role)或权限(Permission)的访问控制。通过在 Spring Security 中配置权限,我们可以实现细粒度的访问控制,确保不同的用户只能访问其权限范围内的资源。

配置角色权限

Spring Security 提供了 hasRolehasAuthority 等方法来进行角色或权限的判断。例如,我们可以根据用户角色来控制他们对资源的访问权限:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")  // 只有角色为 ADMIN 的用户可以访问 /admin 下的页面
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")  // 用户或管理员可以访问 /user 下的页面
            .anyRequest().authenticated()
        .and()
        .formLogin()
        .permitAll();
}

这样,Spring Security 会根据用户的角色来判断他们是否有权限访问指定的 URL。

OAuth2 与 SSO 集成 🔗

1. 什么是 OAuth2?

OAuth2 是一种常用的授权协议,允许第三方应用在不暴露用户密码的情况下,访问用户在服务提供商处的资源。它广泛用于社交媒体登录、第三方服务的授权等场景。

OAuth2 的工作流程大致分为以下几个步骤:

  1. 用户通过客户端应用发起认证请求。
  2. 客户端通过授权码等方式向授权服务器请求访问令牌(Access Token)。
  3. 客户端使用访问令牌访问资源服务器上的用户数据。

2. Spring Security 与 OAuth2 集成

Spring Security 为 OAuth2 提供了完整的集成支持,下面是如何将 OAuth2 和单点登录(SSO)集成到 Spring Boot 应用中的基本步骤。

添加 OAuth2 依赖

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

配置 OAuth2 客户端

application.yml 文件中配置 OAuth2 客户端信息:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: YOUR_CLIENT_ID
            client-secret: YOUR_CLIENT_SECRET
            scope: profile, email
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            authorization-grant-type: authorization_code
            client-name: Google

配置安全性

在 Spring Security 配置中启用 OAuth2 客户端:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/login").permitAll()
                .anyRequest().authenticated()
            .and()
            .oauth2Login();  // 启用 OAuth2 登录
    }
}

总结 🏆

通过今天的学习,我们深入了解了如何使用 Spring Security 来进行安全认证与授权。我们探讨了 Spring Security 的核心功能,如表单认证、JWT 认证、基于角色的访问控制,以及如何集成 OAuth2 和 SSO 等现代认证协议。通过这些功能,我们可以保护我们的应用免受未经授权的访问,确保数据的安全性。

无论是构建一个简单的用户认证系统,还是处理复杂的权限管理和集成第三方认证,Spring Security 都能为我们提供强大的支持。希望通过本篇文章,你能对 Spring Security 的使用有更深入的理解,并能够在实际项目中实现安全、高效的认证与授权机制!🚀

🧧福利赠与你🧧

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学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个月内不可修改。