springsecurity6使用

news2024/11/30 0:28:24

spring security 中的类 :

  • AuthenticationManager : 实现类:ProviderManager
    管理很多的 provider ,,, 经常使用的,DaoAuthenticationProvider , 这个要设置一个 UserDetailService , 查找数据库,,loadUserByUsername() 查找出数据库中的对象,,然后进行比对
spring security 中的配置

配置spring security 也就是配置 过滤器链,,spring security 他有默认的过滤器链,,,通过HttpSecurity 中的 build()方法,会返回一个默认的有拦截的过滤器链
我们一般都是在这个原本的过滤器链上面修改,,而不是重新创建自己的过滤器链,,


    /**
     * 过滤器
     *  : 配置过滤器链
     *  DispatchServlet
     *
     *  DefaultLoginPageGeneratingFilter : 默认登录页面过滤器
     *  DefaultLogoutPageGeneratingFilter : 默认注销页面过滤器
     *  BasicAuthenticationFilter : 请求头认证过滤器
     */


    /**
     * 配置过滤器链  SecurityFilterChain,,spring security 所有功能都是通过过滤器链来提供
     */
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 拦截所有,,经过某些过滤器
//        return new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"));


        // 默认的过滤器链
//        return http.build();


         http.authorizeHttpRequests(p->p.anyRequest().authenticated())
                .formLogin(f->f.usernameParameter("username")
                        .passwordParameter("password")
                        .loginProcessingUrl("/login")
                        .successHandler((req,resp,auth)->{
                            resp.setContentType("application/json;charset=utf-8");
                            Hr hr = (Hr) auth.getPrincipal();
                            hr.setPassword(null);
                            resp.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.ok("登录成功",hr)));
                        })
                        .failureHandler((req,resp,e)->{
                            resp.setContentType("application/json;charset=utf-8");
                            RespBean error = RespBean.error("登录失败");

                            if (e instanceof BadCredentialsException){
                                error.setMessage("密码错误");
                            }else if (e instanceof DisabledException){
                                error.setMessage("用户被禁用");
                            }else if (e instanceof LockedException){
                                error.setMessage("账户被锁定");
                            }else if (e instanceof AccountExpiredException){
                                error.setMessage("账户过期");
                            }else if(e instanceof CredentialsExpiredException){
                                error.setMessage("密码过期");
                            }

                            resp.getWriter().write(new ObjectMapper().writeValueAsString(error));
                        }))
                .csrf(c->c.disable())
                 //异常处理
                 .exceptionHandling(e->e.authenticationEntryPoint((req,resp,ex)->{
                     resp.setContentType("application/json;charset=utf-8");
                     resp.setStatus(401);
                     RespBean error = RespBean.error("尚未登陆,请登录");
                     resp.getWriter().write(new ObjectMapper().writeValueAsString(error));
                 }));

         // 加到 UsernamePasswordAuthenticationFilter前面
         http.addFilterBefore(jsonFilter(), UsernamePasswordAuthenticationFilter.class);

         return  http.build();

        /**
         * spring security 默认key-value
         * UsernamePasswordAuthenticationFilter
         */

    }

UsernamePasswordAuthenticationFilter : 这个是拦截提交的用户名密码的拦截器,,,里面有个attemptAuthentication() 去获取前端传入的用户名密码,
在这里插入图片描述
根据request获取的参数,,,
然而,我们需要通过json传参,,就需要重写这个方法,,并将自己的过滤器加入到spring security的过滤器链中,,

/**
 * 登录传递json
 */
public class JsonFilter extends UsernamePasswordAuthenticationFilter {
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        String contentType = request.getContentType();
        if (contentType.equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) || contentType.equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)){
            // 前端传入的是json
            try {
                // 通过io流,去解析请求体参数,,,比如:文件,json,,,   key-value也可以通过io流获取
                Hr hr = new ObjectMapper().readValue(request.getInputStream(), Hr.class);

                String username = hr.getUsername();
                String password = hr.getPassword();
                UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,
                        password);
                // Allow subclasses to set the "details" property
                setDetails(request, authRequest);
                // 获取认证管理器去认证
                return this.getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }else{
            //  key-value
            return super.attemptAuthentication(request,response);
        }




    }
}

自己新加的过滤器,需要配置自己的 AuthenticationManager , 和用户信息存放的位置:

   /**
     * AuthenticationManager :
     *      实现类:   ProviderManager
     *      管理很多 provider
     * @return
     */
    @Bean
    AuthenticationManager authenticationManager(){
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();

        daoAuthenticationProvider.setUserDetailsService(hrService);

        ProviderManager providerManager = new ProviderManager(daoAuthenticationProvider);
        return providerManager;
    }

配置了自己的 登录filter,, HttpSecurity中配置的formLogin 就失效了,,,需要自己配置loginProcessingUrl, successHandler,failureHandler等信息,,

需要配置自己的 AuthenticationManager 和表明登录信息的存放位子,,,,因为每一次都会从这个存放位置去找用户信息,,如果找到,表示已登录,如果没找到,就是没有登录

   /**
     * 配置了  JsonFilter ,,,    httpsecurity 中的 fromLogin就失效了
     * @return
     */
    JsonFilter jsonFilter(){
        JsonFilter jsonFilter = new JsonFilter();
        jsonFilter.setFilterProcessesUrl("/login");
        jsonFilter.setAuthenticationSuccessHandler((req,resp,auth)->{
            resp.setContentType("application/json;charset=utf-8");
            Hr hr = (Hr) auth.getPrincipal();
            hr.setPassword(null);
            resp.getWriter().write(new ObjectMapper().writeValueAsString(RespBean.ok("登录成功",hr)));
        });
        jsonFilter.setAuthenticationFailureHandler((req,resp,e)->{
            resp.setContentType("application/json;charset=utf-8");
            RespBean error = RespBean.error("登录失败");

            if (e instanceof BadCredentialsException){
                error.setMessage("密码错误");
            }else if (e instanceof DisabledException){
                error.setMessage("用户被禁用");
            }else if (e instanceof LockedException){
                error.setMessage("账户被锁定");
            }else if (e instanceof AccountExpiredException){
                error.setMessage("账户过期");
            }else if(e instanceof CredentialsExpiredException){
                error.setMessage("密码过期");
            }

            resp.getWriter().write(new ObjectMapper().writeValueAsString(error));
        });


        // 需要设置自己的 AuthenticationManager
        jsonFilter.setAuthenticationManager(authenticationManager());

        /**
         *  每一次都会从 httpSession中获取用户,,如果httpsession中没有用户,就会表示成没有登录,,
         *  新配置的 filter 需要告知 ,,用户信息存放在哪里,,
         */

        // 自己配置的filter 需要设置 SecurityContextHolder 存储用户的位置
        jsonFilter.setSecurityContextRepository(new HttpSessionSecurityContextRepository());

        return jsonFilter;
    }

这个用户信息可以存在HttpSessionSecurityContextRepositorysession中,,也可以重写类,存放在其他地方,比如redis

spring security 异常处理,,exceptionHandling, 中authenticationEntryPoint,处理登录失败异常
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1447750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ES6】Promise

Promise 回调地狱 const fs require(fs);fs.readFile(./a.txt, utf-8, (err, data) > {if(err) throw err;console.log(data);fs.readFile(./b.txt, utf-8, (err, data) > {if(err) throw err;console.log(data);fs.readFile(./c.txt, utf-8, (err, data) > {if(er…

斯巴鲁Subaru EDI需求分析

斯巴鲁Subaru是日本运输集团斯巴鲁公司(前身为富士重工)的汽车制造部门,以性能而闻名,曾赢得 3 次世界拉力锦标赛和 10 次澳大利亚拉力锦标赛。 斯巴鲁Subaru EDI 需求分析 企业与斯巴鲁Subaru建立EDI连接,首先需要确…

MQTT的学习与应用

文章目录 一、什么是MQTT二、MQTT协议特点三、MQTT应用领域四、安装Mosquitto五、如何学习 MQTT 一、什么是MQTT MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,设计用于在低带宽、不稳定的网络环境中进行高效的通信…

ITK 图像分割(一):阈值ThresholdImageFilter

效果: 1、itkThresholdImageFilter 该类的主要功能是通过设置低阈值、高阈值或介于高低阈值之间,则将图像值输出为用户指定的值。 如果图像值低于、高于或介于设置的阈值之间,该类就将图像值设置为用户指定的“外部”值(默认情况…

基于JAVA的新能源电池回收系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回收机构模块2.4 电池订单模块2.5 客服咨询模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 E-R 图设计 四、系统展示五、核心代码5.1 增改电池类型5.2 查询电池品类5.3 查询电池回…

联合体与枚举

联合体与枚举 联合体枚举问题 联合体 联合体也是由一个或多个成员构成的数据类型,它最大的特点是只为最大的一个成员开辟空间,其他成员共用这个空间,这个东西也叫共用体!!! union Un {char c;int i; };int main() {union Un un { 0 };un.c 0x01;//先为最大的成员开辟空间un.…

STM32单片机的基本原理与应用(七)

超声波测距实验 基本原理 超声波测距实验是STM32单片机通过控制HC-SR04超声波模块,使其发送超声波,遇到物体反射回超声波来实现距离测量,其原理就是在发射超声波到接收超声波会有一段时间,而超声波在空气中传播的速度为声速&…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-动态内存

目录 一、动态内存运行机制二、动态内存开发流程三、动态内存使用说明四、动态内存核心算法五、动态内存接口六、代码分析(待续...)坚持就有收获 一、动态内存运行机制 动态内存管理,即在内存资源充足的情况下,根据用户需求&…

单个摄像头(单目RGB)实时3D手的跟踪

概述: 通过单个普通RGB摄像头就可以实现3D手的实时跟踪。 来自论文: GANerated Hands for Real-Time 3D Hand Tracking from Monocular RGB 官网地址如下链接: GANerated Hands for Real-Time 3D Hand Tracking from Monocular RGB 应用…

Linux_环境变量_命令行参数

一.环境变量 在Linux中自己写的程序必须要带路径才能运行,相对路径或是绝对路径,但是像ls pwd这样的程序,不带路径也能运行。当你想要运行一个程序时: 如果带有路径的话,则直接将对应路径的程序加载进内存&#xff0…

Linux入门(1)Linux介绍

目录 1. 认识 Linux, 了解 Linux 的相关背景 1.发展史 2. 学会如何使用云服务器 3. 掌握使用远程终端工具 xshell 登陆 Linux 服务器 1. 认识 Linux, 了解 Linux 的相关背景 1.发展史 学习Linux系统编程,你可能要问Linux从哪里来?它是怎么发展的&am…

如何在Spring Boot中启用HTTPS?

在Spring Boot中启用HTTPS是一个增强应用程序安全性的重要步骤。下面我将介绍如何将一个Spring Boot项目配置成支持HTTPS协议。 引入 在现代的网络通信中,安全性成为了一个不能忽视的要求。特别是当我们谈论到数据传输时,保护用户信息的安全性是非常重要…

vue-组件组成和组件通信(四)

组件的三大组成部分 (结构/样式/逻辑) scoped样式冲突 默认情况:写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。 1. 全局样式: 默认组件中的样式会作用到全局 2. 局部样式: 可以给组件加上 scoped 属性, 可以让样式只作用于当前组…

【北邮鲁鹏老师计算机视觉课程笔记】07 Local feature-Blob detection

【北邮鲁鹏老师计算机视觉课程笔记】07 Local feature-Blob detection 1 实现尺度不变性 不管多近多远,多大多小都能检测出来 找到一个函数,实现尺度的选择特性 2 高斯偏导模版求边缘 做卷积 3 高斯二阶导拉普拉斯 看哪个信号能产生最大响应 高斯…

TinUI v5预发布记录

TinUI v5预发布记录 前言新控件滚动选择框菜单按钮 新样式pre1pre2pre3 新功能导入字体文件 前言 TinUI是一个从2021年正式开始并一直维护到现在的小项目,中间经过了四代版本的更新。因为一些原因,2023年,TinUI-4后更新较少。 TinUI发展历程…

【MATLAB】小波神经网络回归预测算法

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 小波神经网络回归预测算法是一种利用小波变换和人工神经网络相结合的方法,用于解决回归预测问题。下面将详细介绍该算法的原理与方法: 小波变换: 小波变…

网络渗透测试:Wireshark抓取qq图片

Wireshark Wireshark Downloadhttps://www.wireshark.org/download.html 简介 WireShark是非常流行的网络封包分析工具,可以截取各种网络数据包,并显示数据包详细信息。常用于开发测试过程中各种问题定位。本文主要内容包括: 1、Wireshar…

内网穿透 | 推荐两个免费的内网穿透工具

目录 1、简介 2、Ngrok 2.1、下载安装 2.2、运行 2.3、固定域名 2.4、配置多服务 3、cpolar 3.1、下载安装 3.2、运行 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应…

【前沿技术杂谈:AI 模型训练成本】到 2030 年,AI 模型训练成本预计将从 1 亿美元增加到 5 亿美元

【前沿技术杂谈:AI 模型训练成本】到 2030 年,AI 模型训练成本预计将从 1 亿美元增加到 5 亿美元 简述五年后,人工智能将掌握在谁的手中? 简述 根据 OpenAI 最近的一份报告,到 2030 年,训练大型 AI 模型的成…

matplotlib从起点出发(13)_Tutorial_13_Autoscaling

0 自动放缩 轴上的限制可以手动设置(例如ax.set_xlim(xmin, xmax)),或者Matplotlib可以根据Axes上已有的数据自动设置它们。此种放缩行为有许多选项,如下所述。 我们将从一个简单的折线图开始,显示自动缩放将轴限制扩展到数据的…