当前位置: 首页 > article >正文

SpringSecurity-前后端分离

在前后端分离的架构中,Spring Security 的配置与传统的单体应用有所不同。为了确保安全性和灵活性,我们需要对 Spring Security 进行适当的调整以适应这种架构。下面将详细介绍如何在前后端分离的应用程序中实现 Spring Security。

1. 理解前后端分离的安全需求

在前后端分离的应用程序中,前端通常是一个独立的 Web 应用或移动应用,而后端提供 RESTful API 或 GraphQL 接口。因此,我们需要考虑以下几点:

  • 认证:用户登录后,前端应该获得一个令牌(如 JWT),并在后续请求中携带此令牌来证明身份。
  • 授权:根据用户的权限级别,控制他们可以访问哪些资源。
  • 跨域资源共享 (CORS):由于前端和后端可能部署在不同的域名上,需要处理 CORS 请求。
  • 会话管理:避免使用基于 Cookie 的会话机制,转而采用无状态的身份验证方式。

2. 选择认证机制

对于前后端分离的应用,推荐使用 JSON Web Token (JWT)OAuth2 来进行认证。这里我们主要讨论 JWT 的实现。

2.1 JSON Web Token (JWT)

JWT 是一种自包含的令牌格式,它允许我们在客户端存储用户信息,并且可以在每次 HTTP 请求时通过 Authorization Header 发送到服务器。JWT 包含三个部分:Header、Payload 和 Signature。

  • 优点

    • 无状态:服务器不需要存储会话信息,减轻了服务器负担。
    • 跨域友好:易于在不同域名之间传递。
    • 简单易用:前端可以直接保存到 localStorage 或 sessionStorage 中。
  • 缺点

    • 安全性依赖于密钥管理:如果私钥泄露,所有签发的 JWT 都可能被伪造。
    • 不适合频繁更改权限场景:因为 JWT 是自签名的,一旦生成就难以撤销。

3. 配置 Spring Security

接下来我们将介绍如何配置 Spring Security 来支持 JWT 认证。

3.1 添加依赖

首先,在 pom.xml 文件中添加必要的依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
3.2 创建 JWT 工具类

创建一个工具类用于生成和解析 JWT:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JwtUtil {

    private static final String SECRET = "your-secret-key"; // 私钥,请确保足够复杂

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .signWith(SignatureAlgorithm.HS512, SECRET.getBytes())
                .compact();
    }

    public static Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET.getBytes())
                .parseClaimsJws(token)
                .getBody();
    }
}
3.3 自定义过滤器

编写一个自定义过滤器来拦截每个请求并验证 JWT:

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String header = request.getHeader("Authorization");

        if (header != null && header.startsWith("Bearer ")) {
            try {
                String jwt = header.substring(7);
                Claims claims = JwtUtil.parseToken(jwt);

                // 设置当前线程的安全上下文
                SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(
                        claims.getSubject(), null, Collections.emptyList()));
            } catch (Exception e) {
                logger.warn("Failed to set user authentication: {}", e.getMessage());
            }
        }

        filterChain.doFilter(request, response);
    }
}
3.4 配置 Spring Security

最后,配置 Spring Security 以集成 JWT 和 CORS 支持:

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.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().and() // 启用 CORS 支持
            .csrf().disable() // 禁用 CSRF 保护(因为我们使用 JWT)
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 禁用会话
            .and()
            .authorizeRequests()
                .antMatchers("/auth/**").permitAll() // 允许未认证用户访问认证接口
                .anyRequest().authenticated(); // 所有其他请求都需要认证

        // 将自定义过滤器添加到过滤器链中
        http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

4. 前端实现

在前端部分,你需要:

  • 在用户登录成功后保存返回的 JWT 到本地存储(如 localStorage 或 sessionStorage)。
  • 在每次发送请求时,在 Authorization 头部添加 Bearer <token>
  • 当遇到 401 或 403 错误时,重定向至登录页面或显示适当的消息提示。

http://www.kler.cn/a/506403.html

相关文章:

  • Linux 常用命令 - chmod 【改变文件或目录权限】
  • Elasticsearch:Jira 连接器教程第一部分
  • 2024年11月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(一)
  • Redis--21--大Key问题解决方案
  • Navicat Premium 原生支持阿里云 PolarDB 数据库
  • Docker的入门
  • 码编译安装httpd 2.4,测试
  • CryptoMamba:利用状态空间模型实现精确的比特币价格预测
  • 基于多个边缘盒子部署的综合视频安防系统的智慧地产开源了
  • Python如何在指定行追加内容
  • IDEA测试报错java.lang.NullPointerException空指针异常解决办法
  • Jetbrains 官方微信小程序插件已上线!
  • 数据存取:存取方式、操作、技术、挑战、相关学术分享
  • Docker 的安装和基本使用[SpringBoot之Docker实战系列] - 第535篇
  • vue中使用OpenLayer加载Geoserver的WMS
  • javascript基础从小白到高手系列一十二:JSON
  • 麦田物语学习笔记:构建游戏的时间系统
  • 常见链表专题相关算法
  • 网络是怎么样连接的--输入www.baidu.com之后网络的底层运行
  • ​HPM6700——以太网通信lwip_udpecho_freertos_socket
  • 《汽车维护与修理》是什么级别的期刊?是正规期刊吗?能评职称吗?
  • Hadoop图书数据分析系统 大屏数据展示 智能图书推荐系统(协同过滤余弦函数) 代码 数据库 全套开发工具
  • C++ 学习
  • AngularJs入门之创建最简单HelloWorld Demo应用
  • Java ee 文件操作和IO
  • python-leetcode-单词规律