【java】RuoYi-Vue前后端分离版本-登陆请求流程解析

news2024/11/14 12:02:06

【java】RuoYiBootstrap多模块版本-登陆请求流程解析
这里它用到了一个安全管理框架Spring Security
你可以通过这篇文章《Spring Security 详解》 去了解它,怎么使用

在这里插入图片描述

登陆请求流程逻辑图

Created with Raphaël 2.3.0 (1)开始 (2)【接下来所有业务都受SecurityConfig配置所过滤】 模块:ruoyi-framework 位置:src/main/java 包名:com.ruoyi.framework.config 类名:SecurityConfig.java 方法:protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception (3)【请求登陆控制器-登录方法】 模块: ruoyi-admin 位置:src/main/java 包名: com.ruoyi.web.controller.system 类名: SysLoginController.java 方法:public AjaxResult login(@RequestBody LoginBody loginBody) 调用方法:String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),loginBody.getUuid()); (4)【登录验证】 模块: ruoyi-framework 位置:src/main/java 包名: com.ruoyi.framework.web.service 类名: SysLoginService.java 方法:public String login(String username, String password, String code, String uuid) 调用方法:authentication = authenticationManager.authenticate(authenticationToken); (5)【走过滤器(Security)拿到用户信息】 模块:ruoyi-framework 位置:src/main/java 包名:com.ruoyi.framework.web.service 类名: UserDetailsServiceImpl.java 方法:public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 调用方法:SysUser user = userService.selectUserByUserName(username); (6)【通过用户名查询用户】 模块:ruoyi-system 位置:src/main/java 包名:com.ruoyi.system.service.impl 类名: SysUserServiceImpl.java 方法:public SysUser selectUserByUserName(String userName) 调用方法: return userMapper.selectUserByUserName(userName); (7)【进入MyBatis接口映射文件】 模块:ruoyi-system 位置:src/main/java 包名:com.ruoyi.system.mapper 类名: SysUserMapper.java 方法:public SysUser selectUserByUserName(String userName); (8)【进入MyBatis的xml配置文件】 模块:ruoyi-system 位置:src/main/resources/mapper/system/ xml文件名: SysUserMapper.xml 方法: selectUserByUserName 代码: <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult"> <include refid="selectUserVo"/> where u.user_name = #{userName} and u.del_flag = '0' </select> (9)结束:返回结果

SecurityConfig配置过滤

  • 模块:ruoyi-framework
  • 位置:src/main/java
  • 包名:com.ruoyi.framework.config
  • 类名:SecurityConfig.java
  • 过滤配置代码位置:114行

过滤配置代码

// 注解标记允许匿名访问的url
            .authorizeHttpRequests((requests) -> {
                permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
                // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
                    // 静态资源,可匿名访问
                    .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                    // 除上面外的所有请求全部需要鉴权认证
                    .anyRequest().authenticated();
            })

SecurityConfig.java 源码

package com.ruoyi.framework.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.filter.CorsFilter;
import com.ruoyi.framework.config.properties.PermitAllUrlProperties;
import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter;
import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl;
import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;

/**
 * spring security配置
 * 
 * @author ruoyi
 */
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Configuration
public class SecurityConfig
{
    /**
     * 自定义用户认证逻辑
     */
    @Autowired
    private UserDetailsService userDetailsService;
    
    /**
     * 认证失败处理类
     */
    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;

    /**
     * 退出处理类
     */
    @Autowired
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

    /**
     * token认证过滤器
     */
    @Autowired
    private JwtAuthenticationTokenFilter authenticationTokenFilter;
    
    /**
     * 跨域过滤器
     */
    @Autowired
    private CorsFilter corsFilter;

    /**
     * 允许匿名访问的地址
     */
    @Autowired
    private PermitAllUrlProperties permitAllUrl;

    /**
     * 身份验证实现
     */
    @Bean
    public AuthenticationManager authenticationManager()
    {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
        return new ProviderManager(daoAuthenticationProvider);
    }

    /**
     * anyRequest          |   匹配所有请求路径
     * access              |   SpringEl表达式结果为true时可以访问
     * anonymous           |   匿名可以访问
     * denyAll             |   用户不能访问
     * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
     * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
     * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
     * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
     * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
     * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
     * permitAll           |   用户可以任意访问
     * rememberMe          |   允许通过remember-me登录的用户访问
     * authenticated       |   用户登录后可访问
     */
    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
    {
        return httpSecurity
            // CSRF禁用,因为不使用session
            .csrf(csrf -> csrf.disable())
            // 禁用HTTP响应标头
            .headers((headersCustomizer) -> {
                headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
            })
            // 认证失败处理类
            .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
            // 基于token,所以不需要session
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            // 注解标记允许匿名访问的url
            .authorizeHttpRequests((requests) -> {
                permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
                // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
                    // 静态资源,可匿名访问
                    .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                    // 除上面外的所有请求全部需要鉴权认证
                    .anyRequest().authenticated();
            })
            // 添加Logout filter
            .logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
            // 添加JWT filter
            .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
            // 添加CORS filter
            .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
            .addFilterBefore(corsFilter, LogoutFilter.class)
            .build();
    }

    /**
     * 强散列哈希加密实现
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
}

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

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

相关文章

基于yolov5猫狗检测

项目简介 该项目使用YOLOv5深度学习框架来检测图像或视频中的猫和狗。YOLOv5&#xff08;You Only Look Once v5&#xff09;是一种高效的物体检测模型&#xff0c;能够快速准确地识别出图像中的目标。本项目具有以下特点&#xff1a; 图像检测&#xff1a;用户可以通过上传图…

Nginx-企业高性能web服务器 超长完整版!只有你想不到 没有你学不到的满满干货!!

Web服务基础介绍 Web 服务器访问流程 按下回车时浏览器根据输入的 URL 地址发送请求报文给服务器。服务器接收到请求报文&#xff0c;会对请求报文进行处理。服务器将处理完的结果通过响应报文返回给浏览器。浏览器解析服务器返回的结果&#xff0c;将结果显示出来。 1. 输入…

苹果手机视频误删怎么恢复?看完拍手叫好的4个方法

试想一下&#xff0c;当你在翻看苹果手机相册的视频&#xff0c;正沉浸在过往的美好回忆中时&#xff0c;手指一不小心触碰到了屏幕上的删除按钮&#xff0c;手机上的视频就这样消失了……面对这样的意外情况&#xff0c;苹果手机视频误删怎么恢复呢&#xff1f;别急&#xff0…

Nuxt学习_基础知识(一)

文章学习来源&#xff0c;nuxt中文网 1. 安装nuxt 指令 npx create-nuxt-app t_nuxt或yarn create nuxt-app f_nuxt 执行指令后按需选择添加自己所需要的相关依赖&#xff0c;若安装出现报错等问题 清除npm、yarn缓存 npm cache clean --force yarn cache clean切换安装命令切…

NSIS - 创建桌面应用程序(Client-Side, CS 或者称为本地应用程序)的安装包

B站视频 C# winform Costura.Fody将多个dll打包生成一个可执行的exe文件中_哔哩哔哩_bilibili 博客 NSIS打包教程 Wnform程序打包-罗分明网络博客 补充:(以下面代码为例) ; 该脚本使用 HM VNISEdit 脚本编辑器向导产生; 安装程序初始定义常量 !define PRODUCT_NAME "sql…

9个超强查找下载化学学科文献的数据库 建议收藏

一、CAS&#xff08;美国化学文摘社&#xff09;数据库 CAS SciFinder Discovery Platform 是由全球科学信息引领者CAS&#xff08;美国化学文摘社&#xff09;出品的新一代的权威科学研究工具&#xff0c;是化学及相关学科智能研究平台&#xff0c;提供全球全面、可靠的化学及…

图片转PDF?小case!这几步操作,让你秒变职场小旋风

嘿&#xff0c;大家在忙碌的工作里&#xff0c;经常得处理一堆文件和照片&#xff0c;尤其是当你想把一堆照片弄成一个PDF文件时&#xff0c;这事儿就显得特别重要。不管是为了做报告、提项目建议还是整理日常工作资料&#xff0c;把照片转成PDF格式&#xff0c;都能让我们工作…

知识付费小程序引领线上直播

亲爱的朋友们&#xff0c;欢迎来到“探索未知领域&#xff0c;知识付费小程序引领知识新探索”线上直播课程&#xff01; 在这个信息爆炸的时代&#xff0c;知识的获取从未如此便捷&#xff0c;但高质量、有深度的知识却仍需我们精心筛选。本次直播课程&#xff0c;将聚焦于知识…

conda切换32位运行环境,解决无法在64位系统中安装32位py

当前系统大部分都64位的&#xff0c;我的conda也是64位的&#xff0c;但是如果需要创建32位的py环境&#xff0c;会发现 conda create -n DouyinLive32 python3.7 --force创建的仍然是32位的&#xff0c;为此我们可以使用切换命令切换。 按一下Windows键&#xff0c;输入Prom…

大数据-94 Spark 集群 SQL DataFrame DataSet RDD 创建与相互转换 SparkSQL

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

数据资产入表,全流程实施指南!

数据成为生产要素已是社会共识&#xff0c;但不是所有数据都有资产价值。数据资源当中被重复使用的那部分才会资产化&#xff0c;具有流通中的定价&#xff0c;有些数据资产被专业开发变成数据产品&#xff0c;具有商品价值。从数据原始资源到数据产品&#xff0c;再到数据资产…

华为LTC流程体系的内涵(附PPT分享)

往期回顾&#xff1a; 企业4A架构&#xff1a;数字化转型的底层方法论&#xff08;附TOGAF资料下载&#xff09; PPT分享&#xff1a;数据治理的方法论、设计思路与方案&#xff08;干货&#xff09; 浅谈数字化转型方法论 110页PPT:xx业务流程优化&#xff08;BPR&#xff…

Linux压缩和解压

目录 压缩和解压类 gzip/gunzip指令 zip/unzip指令 tar指令 压缩和解压类 gzip/gunzip指令 gzip用于压缩文件&#xff0c;gunzip用于解压缩文件。 解压后去掉了gz的后缀。 zip/unzip指令 ​​​​​​​ 将文件压缩后发给别人&#xff0c;别人再解压。 将整个文件压…

Python | Leetcode Python题解之第354题俄罗斯套娃信封问题

题目&#xff1a; 题解&#xff1a; class Solution:def maxEnvelopes(self, envelopes: List[List[int]]) -> int:if not envelopes:return 0n len(envelopes)envelopes.sort(keylambda x: (x[0], -x[1]))f [1] * nfor i in range(n):for j in range(i):if envelopes[j]…

利用srs进行视频流转发

框图如下 docker-compose.yaml如下 rtmp2rtc.conf的配置如下 就增加了 #配置如下 forward {enabled on;#开启转发backend http://192.168.0.131:6789/api/v1/forward; #有视频流数据后会调用这个接口} #回调的参数如下 Received payload: {actionon_forward, server_idvid-k2…

字节微前端框架Garfish

Garfish 是字节跳动开源的微前端框架&#xff0c;旨在应对现代 Web 应用在前端生态繁荣与应用日益复杂化背景下的挑战。本文将介绍如何使用 Garfish&#xff0c;提供代码示例&#xff0c;并与另一流行的微前端框架 Qiankun 进行对比分析。 安装 Garfish 首先&#xff0c;安装…

深度学习11--GAN进阶与变种

基础 GAN 存在的问题 在开始讲解变种之前&#xff0c;首先讲一下GAN 存在的问题。第一个问题就是判别器D太强了&#xff0c;损失都是0。假设判别器D能力强&#xff0c;G vl生成的图片与真实图片相差巨大&#xff0c;G v2生成的图片与真实图片相差不多&#xff0c;但是判别器都能…

01. 真正实现一键自动化生成pdf报告

easypdf使用手册 1. 项目介绍1.1 关于1.2 easypdf 有什么优势1.2 easypdf 可以用来做什么1.3 我们该做哪些准备&#xff1f;如何获取easypdf&#xff1f;1.4 项目演示 文章头部展示的附件pdf文档easypdf是项目执行生成的pdf文档 1. 项目介绍 1.1 关于 \qquad easypdf 是我在基…

Floyd算法(最短路问题)

文章目录 Floyd算法介绍Floyd算法思路代码及讲解 Floyd算法介绍 Floyd算法是一种用于找出加权图中所有顶点间最短路径的动态规划方法。它通过逐步考虑每个顶点作为中转点&#xff0c;检查是否有更短路径。算法首先初始化一个权值矩阵&#xff0c;然后通过三层循环更新矩阵&…

linux操作系统命令-文件系统-用户系统-网络-磁盘-进程-常用特殊字符-重定向-

Shell命令格式 命令提示符&#xff1a; 通常显示为 用户名主机名:目录名 $ 或 用户名主机名:目录名 #&#xff08;对于root用户&#xff09;。~ 表示当前用户的家目录。 命令格式&#xff1a; bash $ 命令 [-选项] [参数1] [参数2] ... $ 或 # 是命令提示符&#xff0c;$…