首页 > 其他分享 >一文彻底搞定Spring Security 认证,实现登陆登出功能

一文彻底搞定Spring Security 认证,实现登陆登出功能

时间:2024-11-04 19:10:51浏览次数:1  
标签:自定义 Spring org 认证 登出 import Security

Spring Security 是一个强大且灵活的安全框架,提供了身份验证(认证)和授权(授权)功能。下面我们将详细介绍 Spring Security 的认证功能流程,并提供自定义实现登录接口的示例,包括自定义认证过滤器和登出功能。

一、Spring Security 认证流程的深入分析

Spring Security 的认证流程是多层次的,涉及多个组件的协作。以下是每个步骤的深入分析:

  1. 请求拦截

    当用户请求一个受保护的资源时,Spring Security 会使用过滤器链来处理请求。FilterChainProxy 是 Spring Security 的核心过滤器,它将请求传递给注册的过滤器链。

  2. 认证过滤器

    默认情况下,UsernamePasswordAuthenticationFilter 会被用作处理用户名和密码的认证。它从请求中提取认证信息,通常是通过 POST 请求的表单数据传递。

    关键方法 attemptAuthentication 中,使用 AuthenticationManager 来处理认证请求。AuthenticationManager 负责委托认证给具体的认证提供者。

  3. 用户详情服务(UserDetailsService)

    认证过程中的一个重要步骤是从数据源中加载用户信息。UserDetailsService 接口提供了一个 loadUserByUsername 方法,负责根据用户名加载用户详情。

    通常,用户信息存储在数据库中,UserDetails 对象将包含用户名、密码和权限信息。Spring Security 提供了多种 UserDetailsService 的实现,开发者也可以自定义实现。

  4. 密码验证

    一旦获取到用户详情,接下来的步骤是验证密码。使用 PasswordEncoder 对用户输入的密码与存储在数据库中的密码进行比对。

    Spring Security 支持多种加密算法(如 BCrypt、PBKDF2、SCrypt),并允许开发者自定义密码编码器。

  5. 成功和失败处理

    认证成功后,successfulAuthentication 方法被调用。在此方法中,开发者可以实现自定义的成功逻辑,例如返回 JWT 令牌、设置用户会话等。

    如果认证失败,unsuccessfulAuthentication 方法会被调用,可以根据需要返回错误消息或重定向到登录页面。

二、自定义登录接口的实现

1. 自定义认证过滤器的设计

创建自定义认证过滤器时,需要继承 UsernamePasswordAuthenticationFilter 并重写相应的方法。以下是详细实现:

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    public CustomAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        return authenticationManager.authenticate(authenticationToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        // 可以返回用户信息或 JWT 令牌
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_OK);
        ObjectMapper objectMapper = new ObjectMapper();
        String token = "some_generated_jwt"; // 实际上要生成 JWT
        response.getWriter().write(objectMapper.writeValueAsString("token: " + token));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().write("{\"error\": \"" + failed.getMessage() + "\"}");
    }
}

2. 配置 Spring Security 的详细步骤

在配置类中,我们将添加自定义过滤器并设置用户存储方式。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置用户存储方式
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER")
            .and()
            .withUser("admin").password("{noop}admin").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        CustomAuthenticationFilter customFilter = new CustomAuthenticationFilter(authenticationManagerBean());
        customFilter.setFilterProcessesUrl("/login"); // 自定义登录路径

        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/login").permitAll() // 允许访问登录接口
            .anyRequest().authenticated() // 其他请求需要认证
            .and()
            .addFilter(customFilter) // 添加自定义认证过滤器
            .logout()
            .logoutUrl("/logout") // 自定义登出路径
            .logoutSuccessUrl("/login?logout") // 登出成功后的重定向地址
            .invalidateHttpSession(true) // 登出时使 HTTP 会话失效
            .deleteCookies("JSESSIONID"); // 删除指定的 Cookie
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

三、登出功能的实现

在 Spring Security 中,登出功能非常简单。配置登出路径和成功重定向即可。在上述配置中,我们已经为登出功能添加了以下配置:

  • logoutUrl("/logout"):指定登出的 URL。
  • logoutSuccessUrl("/login?logout"):登出成功后的重定向 URL。
  • invalidateHttpSession(true):登出时使 HTTP 会话失效。
  • deleteCookies("JSESSIONID"):在登出时删除指定的 Cookie。

四、设计考虑与常见问题

  1. 设计考虑

    灵活性:自定义认证过滤器允许我们实现不同的认证逻辑,如 OAuth2、JWT 等,保持系统的灵活性。

    安全性:在实现过程中,确保敏感信息(如密码)不被明文传输和存储,推荐使用 HTTPS 和合适的密码加密方式。

    错误处理:对失败的认证提供明确的反馈,方便用户理解问题所在,提升用户体验。

  2. 常见问题

    跨域问题:在前后端分离的应用中,登录接口可能会遇到跨域请求问题。可以通过设置 CORS 策略来解决。

    状态管理:如果使用 JWT 进行认证,需注意如何管理状态和续期机制。

    并发登录问题:需要考虑多个设备或浏览器同时登录的情况,可能需要实现会话管理。

标签:自定义,Spring,org,认证,登出,import,Security
From: https://www.cnblogs.com/lgx211/p/18525997

相关文章

  • 基于java+SpringBoot+Vue的大学生就业招聘系统设计与实现
    项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot+mybatis+Maven+mysql5.7或8.0等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个......
  • 基于java+SpringBoot+Vue的校园资料分享平台设计与实现
    项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot+mybatis+Maven+mysql5.7或8.0等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个......
  • Spring Boot代理问题
    在SpringBoot2.x中,AOP(面向切面编程)默认使用CGLIB(CodeGenerationLibrary)来实现类的代理。CGLIB代理是通过在运行时生成目标类的子类来增强目标类的方法。这种方式允许对没有实现接口的类进行代理。以下是一些原因和机制解释,说明为什么Spring在AOP中默认使用CGLIB。......
  • 基于Springboot逍遥大药房管理系统+LW+ppt
    博主介绍:✌全网粉丝3W+,csdn特邀作者、CSDN新星计划导师、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视......
  • Spring Boot日志
     博主主页: 码农派大星.  数据结构专栏:Java数据结构 数据库专栏:MySQL数据库JavaEE专栏:JavaEE软件测试专栏:软件测试关注博主带你了解更多知识目录1.⽇志概述1.1⽇志的⽤途1.系统监控2.数据采集3.⽇志审计2.⽇志使⽤2.1打印⽇志2.1.1在程序中......
  • spring-framework的StopWatch类详解,每个方法带有具体的例子
    目录简介:StopWatch类的应用场景:StopWatch类提供了以下一些主要方法:start():stop():reset():split():unsplit():getTime():getStartTime():toString():isStarted():isStopped():示例代码:以下是一个使用StopWatch测量代码执行时间的简单示例:以下是一个使用StopWatch类的复杂示例,该示例演......
  • Springboot+MyBatis批量插入数据的三种方式
    1.背景介绍在开发过程中,我们经常会遇到往数据库表中插入大量数据的场景,比如excel批量导入数据。那么该如何快速地插入数据呢?我们可以考虑使用批量插入来实现,实测100000条数据添加,后附具体实现代码。2.方案介绍2.1第一种方案,用for语句循环插入(不推荐)用一个for循环,把数据......
  • SpringBoot数字迎新系统u0p2s 本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1
    题目:SpringBoot数字迎新系统u0p2s进度安排:(1)2024年11月1日-2024年11月15日 确定选题,下达任务书,撰写开题报告;(2)2024年11月15日-2024年12月20日提交开题报告定稿;(3)2024年12月21日-2025年3月14日 完成选题的设计、论文大纲的撰写;(4)2025年3月15日-2025年3月21日  毕业(设......
  • SpringBoot时间管理系统quqp0 本系统(程序+源码+数据库+调试部署+开发环境)
    开题报告内容一、课题背景与意义在信息爆炸和工作节奏日益加快的今天,时间管理成为个人和组织高效运作的关键因素。然而,很多人面临时间分配不合理、任务拖延、工作效率低下等问题。因此,开发一套科学、智能的时间管理系统,帮助用户合理规划时间、提高工作效率,具有重要的现实意义......
  • SpringBoot生活艺术馆管理系统4b9eu 本系统(程序+源码+数据库+调试部署+开发环境)带论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表系统内容:用户,员工,类别,藏品信息,出库登记,入库登记,藏品修复开题报告内容一、项目背景与意义随着人们精神文化生活需求的日益增长,生活艺术馆作为艺术、文化......