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

使用 Spring Security的一些常用功能

在实际开发中,Spring Security 常常涉及一些常用的功能。以下是一些在开发中经常使用的 Spring Security 功能:

1. PasswordEncoder Bean(密码加密)

这段配置使用 BCryptPasswordEncoder 作为密码加密算法。它是 Spring Security 中常用的密码加密方式,通常用于存储和验证用户的密码。

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

2. 跨域配置(CORS)

配置跨域请求源、请求方法和请求头,允许前端应用跨域访问后端接口。该功能在前后端分离的应用中非常常见,尤其是需要不同域名访问同一服务时。

@Bean
public CorsConfigurationSource configurationSource() {
    UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
    corsConfiguration.setAllowedMethods(Arrays.asList("*"));
    corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
    urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);
    return urlBasedCorsConfigurationSource;
}

3. 自定义登录页面和失败处理

配置自定义的登录页面以及登录成功和失败时的处理逻辑。这是常见的安全性需求,尤其是在用户体验中需要提供定制的登录界面。

.formLogin(formLogin -> {
    formLogin.loginProcessingUrl("/login")
             .successHandler(myAuthenticationSuccessHandler)
             .failureHandler(myAuthenticationFailHandler);
})

 一般在登录成功的回调的处理器当中,我们会生成token并且存入Redis当中,在后续的拦截器当中从Redis获取token并且认证

4. 自定义登出处理

配置自定义的退出登录 URL 及退出成功后的处理。通常需要在登出成功后清理用户会话或进行其他操作。

.logout(logout -> {
    logout.logoutUrl("/logout")
          .logoutSuccessHandler(myLogoutSuccessHandler);
})

5. 请求授权(授权控制)

配置不同的 URL 路径的访问权限,允许一些 URL 对所有用户开放(如登录页面、验证码等),并限制其他 URL 需要认证才能访问。

.authorizeHttpRequests(authorizeHttpRequests -> {
    authorizeHttpRequests
        .requestMatchers("/toLogin", "/common/captcha").permitAll()
        .anyRequest().authenticated();
})

6. 禁用 CSRF(跨站请求伪造)保护

禁用 CSRF 防护,通常在使用无状态认证(如 JWT)时需要禁用 CSRF,因为它依赖于会话。

.csrf(csrf -> {
    csrf.disable();
})

7. Session 管理

设置无状态的会话管理,即不创建会话,每次请求都需要进行身份认证。通常配合 JWT 使用。

.sessionManagement(sessionManagement -> {
    sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
})

8. Token 过滤器

在 Spring Security 的过滤器链中加入自定义的 Token 过滤器(通常用于验证 JWT),确保每个请求都携带正确的认证信息。

对于 RESTful API 和前后端分离的应用,JWT 是一种常见的认证方式。Spring Security 可以与 JWT 配合使用来实现无状态认证。

你可以在 Spring Security 配置中添加一个 JWT 过滤器,拦截请求,提取 JWT 并进行认证。

示例:

 // 在登录filter 之后添加一个token过滤器 确保退出登录的时候可以获取到认证信息
                .addFilterBefore(tokenFilter, LogoutFilter.class)

tokenFilter:

@Component
public class TokenFilter  extends OncePerRequestFilter {


    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.setContentType("application/json;charset=UTF-8");

        // 获取请求路径
        String requestURI = request.getRequestURI();
        // 判断是否是登录请求 登录请求不需要验证
        if (requestURI.equals("/login")) {
            filterChain.doFilter(request, response);
        } else {
            // 取出请求头中的token
            String token = request.getHeader("token");
            // 判断token是否有内容
            if (!StringUtils.hasText(token)) {
                // 没有值
                R result = R.builder().code(901).msg("token不能为空").build();
                response.getWriter().write(JSONUtil.toJsonStr(result));
            } else {
                boolean verify = false;
                try {
                    // 验证通过了为true  这里需要捕获异常
                    verify = JWTUtil.verify(token, Constant.JWT_SECRET.getBytes());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (!verify) {
                    // token无效
                    R result = R.builder().code(902).msg("token无效").build();
                    response.getWriter().write(JSONUtil.toJsonStr(result));
                } else {
                    JSONObject payload = JWTUtil.parseToken(token).getPayloads();
                    String userJson = payload.get("user", String.class);

                    TUser tUser = JSONUtil.toBean(userJson, TUser.class);
                    if (!token.equals(redisTemplate.opsForValue().get(Constant.REDIS_TOKEN_PREFIX + tUser.getId()))) {
                        R result = R.builder().code(903).msg("请求token错误").build();
                        response.getWriter().write(JSONUtil.toJsonStr(result));
                    } else {
                        // 验证通过了,要在Spring Security的上下文当中需要防止一个认证对象
                        // 这样的话 Spring Security 在执行后续的Filter的时候,才知道这个人是已经登录了的
                        UsernamePasswordAuthenticationToken authenticationToken
                                = new UsernamePasswordAuthenticationToken(tUser, null, tUser.getAuthorities());
                        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

                        // 放行
                        filterChain.doFilter(request, response);
                    }
                }
            }
        }
    }
}

需要注意的是当验证通过了之后,需要设置Authentication 认证对象, UsernamePasswordAuthenticationToken 是其一个实现类。

9. 访问权限拒绝处理

配置权限不足时的处理逻辑,通常用来返回友好的错误信息或页面。

.exceptionHandling(exceptionHandling -> {
    exceptionHandling.accessDeniedHandler(myAccessDeniedHandler);
})

相关文章:

  • 众乐影音-安卓NAS-Player的安装和设置说明
  • Beyond Compare 4注册激活方法
  • 农用车一键启动工作原理
  • docker简单使用
  • 如何使用jenv工具管理多个JDK版本
  • 4、匿名函数lambda的使用
  • 从碎片化到标准化:案例详解 MCP 如何重塑 AI Agent 开发生态?
  • 嵌入式基础知识学习:UART是什么?
  • Elasticsearch:可配置的推理 API 端点分块设置
  • 并查集——108. 冗余连接
  • Fourier-Lerobot——把斯坦福人形动作策略iDP3封装进了Lerobot(含我司七月人形研发落地实践)
  • HCL—我与虚拟机的爱恨情仇[特殊字符][特殊字符]‍[特殊字符]️
  • C++ --- 多态
  • 破解PDF转Word难题:如何选择高效、安全的转换工具?
  • C++核心语法快速整理
  • 【redis】事务详解,相关命令multi、exec、discard 与 watch 的原理
  • 操作系统核心问题解析(目的/定位、管理思想:先描述,再组织、 库函数与系统调用的关系)
  • 使用 ncurses 库创建文本用户界面:基础函数详解
  • RK3588开发笔记-DDR4降频实战与系统稳定性优化
  • Jmeter分布式测试的注意事项和常见问题
  • 国家能源局通报上月投诉情况:赤峰有群众反映电费异常增高,已退费
  • 国台办:相关优化离境退税政策适用于来大陆的台湾同胞
  • 移动互联网未成年人模式正式发布
  • 民生银行一季度净利127.42亿降逾5%,营收增7.41%
  • 深入贯彻中央八项规定精神学习教育中央指导组派驻地方和单位名单公布
  • 以“最美通缉犯”为噱头直播?光明网:违法犯罪不应成网红跳板