Spring Boot的安全性:集成Spring Security进行身份验证和授权!

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

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

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

前言 🤔

在现代Web应用中,安全性是一个至关重要的部分。身份验证授权是确保应用安全的基础,而Spring Boot通过集成Spring Security来简化这些安全性功能的实现。通过Spring Security,我们可以轻松地添加身份验证、授权、权限控制等安全功能。今天,我们将深入了解如何将Spring Security与Spring Boot集成,使用基本认证JWT认证进行身份验证,并配置权限控制,确保我们的应用安全可靠。🚀

目录 📋

  1. 集成Spring Security进行身份验证和授权 🔑
  2. 基本认证与JWT认证 🔒
  3. 配置Spring Security的权限控制 🔐

1. 集成Spring Security进行身份验证和授权 🔑

Spring Security是一个强大的安全框架,它提供了认证(Authentication)和授权(Authorization)机制,可以用于保护应用程序的资源。Spring Boot集成Spring Security非常简单,只需要少量配置,Spring Boot会自动为我们提供一个基本的安全机制。

1.1 添加Spring Security依赖

首先,我们需要在pom.xml文件中添加Spring Security的依赖:

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

Spring Boot Starter Security会自动配置Spring Security,提供默认的安全设置,像是登录界面、基本的身份验证机制等。

1.2 Spring Security的自动配置

默认情况下,Spring Security会启用内存中的用户身份验证,并为所有的HTTP请求启用基本的认证机制。比如,如果你没有配置用户名和密码,Spring Security会使用默认的用户user)和自动生成的密码。

# 查看自动生成的密码
spring.security.user.name=user
spring.security.user.password=password

当你启动Spring Boot应用时,Spring Security会自动启用基本认证。你可以通过访问任何保护资源(例如/)来测试登录页面,系统会要求输入用户名和密码。

1.3 创建自定义的安全配置

如果我们想要更细致地控制Spring Security的行为,我们可以通过自定义安全配置类来替代默认的设置。下面是一个简单的自定义配置,启用基于表单的身份验证,并允许访问某些特定资源。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login", "/signup").permitAll() // 允许访问的资源
                .anyRequest().authenticated() // 其他请求需要身份验证
            .and()
            .formLogin()  // 启用表单登录
                .loginPage("/login")  // 自定义登录页面
                .permitAll()
            .and()
            .logout()
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 在内存中创建一个用户
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("{noop}password")  // 密码需要加密,这里使用noop表示不加密
            .roles("USER");
    }
}

在这个配置中,我们定义了:

  • /login/signup 页面可以公开访问,不需要身份验证。
  • 其他所有请求都需要用户认证。
  • 使用内存中创建的用户进行身份验证。

2. 基本认证与JWT认证 🔒

Spring Security支持多种身份验证方式,基本认证JWT认证是最常见的两种。

2.1 基本认证

基本认证(Basic Authentication)通过HTTP头部的Authorization字段传递用户名和密码。在Spring Security中,基本认证是默认启用的。我们可以通过如下方式来配置和测试基本认证。

  • 请求头格式:

    Authorization: Basic base64(username:password)
    

    例如,user:password的Base64编码是dXNlcjpwYXNzd29yZA==,所以请求头会变成:

    Authorization: Basic dXNlcjpwYXNzd29yZA==
    

2.2 JWT认证

JWT(JSON Web Token)是一种非常流行的认证方式,它通过将认证信息封装在一个token中,避免了每次请求都进行数据库查询来验证用户身份。JWT认证一般用于无状态(Stateless)应用,它比基本认证更加安全且高效。

2.2.1 生成JWT Token

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

@Component
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.2.2 配置JWT过滤器

为了将JWT集成到Spring Security中,我们需要创建一个过滤器(JwtAuthenticationFilter),用来从请求头中获取JWT并验证其有效性。

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @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);  // 去除"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);
    }
}
2.2.3 配置Spring Security集成JWT

最后,配置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()
            .and()
            .csrf().disable();
    }
}

3. 配置Spring Security的权限控制 🔐

Spring Security还提供了强大的权限控制功能。我们可以通过角色(Role)和权限(Permission)来限制用户访问不同的资源。

3.1 基于角色的权限控制

你可以通过@PreAuthorize注解在方法级别实现基于角色的权限控制:

@PreAuthorize("hasRole('ADMIN')")
public String adminMethod() {
    return "Hello Admin!";
}

在这个例子中,只有具有ADMIN角色的用户才能访问adminMethod()方法。

3.2 URL级别的权限控制

在Spring Security的配置中,我们可以通过authorizeRequests()来控制URL的访问权限。例如,我们希望/admin/**路径只能被ADMIN角色的用户访问:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().authenticated()
        .and()
        .formLogin();
}

3.3 配置角色和权限

在Spring Security中,我们可以通过GrantedAuthority来为用户分配权限。Spring Security会根据用户的角色和权限自动决定是否允许访问某个资源。

public class MyUserDetails implements UserDetails {
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
    }
}

总结 🌟

通过集成Spring Security,Spring Boot应用可以轻松实现复杂的身份验证和授权功能。通过基本认证JWT认证,我们可以确保用户身份的安全性,并通过Spring Security的权限控制来细粒度地控制不同角色的访问权限。无论是内存用户认证,还是基于JWT的无状态认证,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个月内不可修改。