三分钟快速上手SpringSecurity框架

news2024/11/11 8:39:43

导入依赖框架

        web 框架(spring-boot-starter-web)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        springSecurity 框架(spring-boot-starter-security)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

导入框架之后、当前应用已经具备验证功能

  • 用户名默认为user、密码为启动窗口打印信息

  • 默认登陆页(存在问题、每次需要记录登录密码)

  •  配置文件配置固定用户名、密码


自定义功能实现(用户信息从数据库获取)

        方式一: 

  1. 导入数据源依赖 mysql\mybatis,配置数据源信息

      <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.28</version>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.3</version>
            </dependency>
  2. 直接配置查询 sql (select username,password from s_usr where username = ?)

    package com.bu.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    import javax.sql.DataSource;
    
    /**
     * @author haizhuangbu
     * @date 2024/5/15 16:35
     * @mark WebSecurityConfigImpl
     */
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfigImpl extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private DataSource dataSource;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.jdbcAuthentication()
                    // 配置数据源
                    .dataSource(dataSource)
                    // 查询sql
                    .usersByUsernameQuery("select username,password,'Y' enabled from s_usr where username = ?")
                    .authoritiesByUsernameQuery("select username,authority\n" +
                            "from authorizes where username = ?");
        }
    
    
        // 不进行解密、直接对比
        @Bean
        public PasswordEncoder passwordEncoder() {
            return NoOpPasswordEncoder.getInstance();
        }
    
    }
    
  3. 此时用户信息就是去数据库查询的 (用户信息表 创建包含用户密码关键字段即可)

    create table s_usr
    (
        user_id     varchar(36) not null
            primary key,
        username    varchar(36) null,
        password    varchar(36) null,
        create_time datetime    null,
        modify_time datetime    null,
        enable      char(2)     null comment 'Y 生效 N 失效'
    );
    
    
    
    create table authorizes
    (
        username  varchar(36),
        authority varchar(36)
    );
    
    
    
    insert into s_usr
    values ('1', 'admin', 'admin', now(), now(), 'Y');

        方式二:

  1. 导入数据源配置信息同方式一相同           

  2. 重写springSecurity 的几个组件

    1. UserDetailsService 用户信息查询接口(内部具体编写查询逻辑 )
      package com.bu.config;
      
      import com.bu.sys.user.dao.UserDetailsDao;
      import com.bu.sys.user.dto.SUsrDto;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.security.core.userdetails.UserDetails;
      import org.springframework.security.core.userdetails.UserDetailsService;
      import org.springframework.security.core.userdetails.UsernameNotFoundException;
      import org.springframework.stereotype.Component;
      
      /**
       * @author haizhuangbu
       * @date 2024/5/15 16:22
       * @mark AuthUserServiceImpl
       */
      @Component
      public class AuthUserServiceImpl implements UserDetailsService {
      
      
          @Autowired
          private UserDetailsDao userDetailsDao;
      
          @Override
          public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
              SUsrDto sUsrDto = userDetailsDao.findSUsrByUsername(username);
              return sUsrDto;
          }
      }
      
      
      
      package com.bu.sys.user.dao;
      
      import com.bu.sys.user.dto.SUsrDto;
      import org.apache.ibatis.annotations.Select;
      
      /**
       * @author haizhuangbu
       * @date 2024/5/15 17:15
       * @mark UserDetailsDao
       */
      public interface UserDetailsDao {
      
          @Select("select * from s_usr where username = #{username}")
          SUsrDto findSUsrByUsername(String username);
      
      }
      
      
      
    2. PasswordEncoder 加解密工具
      
          // 不进行解密、直接对比
          @Bean
          public PasswordEncoder passwordEncoder() {
              return NoOpPasswordEncoder.getInstance();
          }
      

    3. UserDetail 用户信息
      package com.bu.sys.user.dto;
      
      import org.springframework.security.core.GrantedAuthority;
      import org.springframework.security.core.userdetails.UserDetails;
      
      import java.util.Collection;
      
      /**
       * @author haizhuangbu
       * @date 2024/5/15 17:16
       * @mark SUsrDto
       */
      public class SUsrDto implements UserDetails {
      
          private String username;
      
          private String password;
      
      
          public String getUsername() {
              return username;
          }
      
          @Override
          public boolean isAccountNonExpired() {
              return true;
          }
      
          @Override
          public boolean isAccountNonLocked() {
              return true;
          }
      
          @Override
          public boolean isCredentialsNonExpired() {
              return true;
          }
      
          @Override
          public boolean isEnabled() {
              return true;
          }
      
          public void setUsername(String username) {
              this.username = username;
          }
      
          @Override
          public Collection<? extends GrantedAuthority> getAuthorities() {
              return null;
          }
      
          public String getPassword() {
              return password;
          }
      
          public void setPassword(String password) {
              this.password = password;
          }
      }
      
    4.  AuthenticationProvider 验证流程
      package com.bu.config;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.security.authentication.AuthenticationProvider;
      import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
      import org.springframework.security.core.Authentication;
      import org.springframework.security.core.AuthenticationException;
      import org.springframework.security.core.userdetails.UserDetails;
      import org.springframework.security.core.userdetails.UserDetailsService;
      import org.springframework.security.core.userdetails.UsernameNotFoundException;
      import org.springframework.security.crypto.password.PasswordEncoder;
      import org.springframework.stereotype.Component;
      
      /**
       * @author haizhuangbu
       * @date 2024/5/15 17:20
       * @mark UserAutorizedServiceImpl
       */
      @Component
      public class UserAuthorizedServiceImpl implements AuthenticationProvider {
      
          @Autowired
          private UserDetailsService userDetailsService;
      
      
          @Autowired
          private PasswordEncoder passwordEncoder;
      
          @Override
          public Authentication authenticate(Authentication authentication) throws AuthenticationException {
      
              // 查询用户信息
              UserDetails userDetails = userDetailsService.loadUserByUsername(authentication.getName());
      
              if (userDetails == null) {
                  throw new UsernameNotFoundException("用户信息不存在");
              }
      
      
              if (!passwordEncoder.matches(userDetails.getPassword(), (String) authentication.getCredentials())) {
      
                  throw new UsernameNotFoundException("密码不正确");
      
              }
      
              return new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword());
          }
      
          @Override
          public boolean supports(Class<?> aClass) {
              return true;
          }
      }
      
  3.  验证组件交给springSecurity (同数据源方式类似)

    package com.bu.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    import javax.sql.DataSource;
    
    /**
     * @author haizhuangbu
     * @date 2024/5/15 16:35
     * @mark WebSecurityConfigImpl
     */
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfigImpl extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserAuthorizedServiceImpl userAuthorizedService;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(userAuthorizedService);
        }
    
    
    
    
    }
    

配置其他信息(成功跳转、失败跳转....)

   // 非页面列表页可以无权限访问外、其他都需要验证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // permitAll 放行路径
                .antMatchers("/login", "/blogs/listAllBlogs", "/blogs/listBloggerInfo", "/theme/listAll")
                .permitAll()
                .anyRequest().authenticated()
                .and().formLogin() // 默认 login 登陆路径
                .failureHandler(failLoginHandler)// 成功处理逻辑
//                .defaultSuccessUrl("/success")
//                .failureUrl("/error")
                .and().addFilterAfter(tokenFilter, BasicAuthenticationFilter.class)
        ;

        http.csrf().disable();

        http.cors().disable();
    }

详细配置思维导图

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

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

相关文章

MySQL基础使用指南

难度就是价值所在。大家好&#xff0c;今天给大家分享一下关于MySQL的基础使用&#xff0c;MySQL 是一个流行的关系型数据库管理系统&#xff0c;被广泛应用于各种类型的应用程序开发中。本文中将介绍 MySQL 的基础使用方法&#xff0c;包括创建数据库、创建表格以及进行增删改…

景源畅信数字:做抖音切片的方法分享?

一提起抖音切片&#xff0c;很多人可能会想到那些让人眼前一亮的短视频。它们通常短小精悍&#xff0c;内容丰富多彩&#xff0c;能够迅速吸引观众的注意力。但是&#xff0c;如何制作出这样的切片视频呢?这就是我们今天要探讨的问题。 一、选材与剪辑 制作抖音切片&#xff0…

判断上三角矩阵 分数 15

题目展示&#xff1a; 代码展示&#xff1a; 点这里&#xff0c;输入题目名称即可检索更多题目答案 ​#include<stdio.h>int main() {//T-tint t 0;scanf("%d",&t);while(t--)//循环t次&#xff0c;处理t个矩阵{int n 0;scanf("%d",&n);…

自学VBA 设置单元格文字格式 笔记

一.设定对应单元格对应需要显示的格式 Cells(1, 1).Font.Size 18 字体大小 Cells(1, 2).Font.Color RGB(255, 0, 0) 字体颜色 Cells(1, 3).Font.Name "黑体" 字体类型 Cells(1, 4).Font.Italic True 字体斜体 Cells(1, 5).Font.FontStyle "BOLD"…

创新指南 | 企业AI战略 实施方案探讨(上):如何构建基于AI的新商业模型和业务场景

2023年以ChatGPT为代表的生成式AI推出以来&#xff0c;从投资界到企业界都掀起了一股热潮。那么从企业角度来看&#xff0c;生成式AI到底能为业务带来哪些增量呢&#xff1f;企业如何构建基于AI的商业模式并进行落地实施呢&#xff1f; 企业AI战略 实施方案探讨分为上下两篇&am…

开发常用的实体属性转化API,copyProperties方法的用途,需要注意的点。

目录 1. 摘要 2. 传统 set 方法转化属性 3. cn.hutool.core.bean.BeanUtil 包下 copyProperties 方法 3.1 转化对象属性多于原始对象属性 3.2 转化对象属性少于原始对象属性 3.3 转化对象属性与原始对象属性存在差 4. org.springframework.beans.BeanUtils 包下 copyPro…

几个排序器的verilog及其资源占用、延时分析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 因为课题需要&#xff0c;调研了几个快速排序方法&#xff0c;并手写或者改进了若干待测试对象&#xff0c;包括记分板型冒泡排序&#xff08;这个是别人的&#xff09…

不相交集合的数据结构

一、不相交集合的操作 不相交集合的数据结构维护了一组不相交动态集的集合 &#xff0c;用集合中的某个成员作为代表标识集合。 集合在没有修改的情况下每次访问代表得到的答案是相同的&#xff0c;此外在其它一些应用中&#xff0c;可能按照规定选择集合的代表&#xff0c;例如…

Java:使用BigDecimal、NumberFormat和DecimalFormat保留小数

一、代码和调试结果 1.1 BigDecimal ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fa36749de8124266a730817710fdf737.png) 1.2 DecimalFormat 1.3 NumberFormat 二、原代码 BigDecimalUtil.java 代码 package utils;import java.math.BigDecimal; import jav…

NAT技术总结与双向NAT配置案例

NAT的转换方式&#xff1a; 1.静态转换&#xff1a;固定的一对一IP地址映射。 interface GigabitEthernet0/0/1 ip address 122.1.2.24 nat static global 122.1.2.1 inside 192.168.1.1 #在路由器出接口 公网地址 私网地址。 2.动态转换&#xff1a;Basic NAT nat address-gr…

[ROS 系列学习教程] 建模与仿真 - URDF 建模实践

ROS 系列学习教程(总目录) 本文目录 一、机器人结构组成二、新建功能包三、编写launch文件四、创建底盘五、添加轮子六、添加其他部件七、解决部分实体位于地面以下的问题 前文介绍了URDF建模与URDF语法&#xff0c;接下来介绍怎么使用URDF从零构建一个机器人模型并在rviz中显示…

智能防疫电梯模拟控制系统设计-设计说明书

设计摘要&#xff1a; 本设计是基于单片机的智能防疫电梯模拟控制系统&#xff0c;主要实现了多项功能。首先&#xff0c;系统进行无接触测温&#xff0c;如果温度正常则可以启动电梯运行&#xff0c;如果温度异常则电梯会报警提示有乘客体温异常&#xff0c;电梯不会运行。其…

Java——CLASSPATH配置

什么是CLASSPATH&#xff1f; 答&#xff1a; classpath类似于windows中的系统环境变量path。 在windows中&#xff0c;如果要想在DOS命令窗口中执行一个程序。系统会先去当前文件路径下找对应命令的执行程序。如果找不到&#xff0c;就会到系统环境变量path中挨个遍历每一个路…

代码随想录算法训练营第二十五天:树的最后学习

代码随想录算法训练营第二十五天&#xff1a;树的最后学习 如果不对递归有深刻的理解&#xff0c;本题有点难 单纯移除一个节点那还不够&#xff0c;要修剪&#xff01; #669. 修剪二叉搜索树 力扣题目链接(opens new window) 给定一个二叉搜索树&#xff0c;同时给定最小边界…

vs2019 c++里用 typeid() . name () 与 typeid() . raw_name () 测试数据类型的区别

&#xff08;1&#xff09; 都知道&#xff0c;在 vs2019 里用 typeid 打印的类型不大准&#xff0c;会主动去掉一些修饰符&#xff0c; const 和引用 修饰符会被去掉。但也可以给咱们验证学到的代码知识提供一些参考。那么今天发现其还有 raw_name 成员函数&#xff0c;这个函…

Qt多文档程序的一种实现

注&#xff1a;文中所列代码质量不高&#xff0c;但不影响演示我的思路 实现思路说明 实现DemoApplication 相当于MFC中CWinAppEx的派生类&#xff0c;暂时没加什么功能。 DemoApplication.h #pragma once#include <QtWidgets/QApplication>//相当于MFC中CWinAppEx的派生…

【RAG 论文】IRCoT:基于 CoT 的交叉检索解决多步骤问题

论文&#xff1a;Interleaving Retrieval with Chain-of-Thought Reasoning for Knowledge-Intensive Multi-Step Questions ⭐⭐⭐⭐ ACL 2023, arXiv:2212.10509 Code: github.com/stonybrooknlp/ircot 论文速读 大多数 RAG 都是一次检索来辅助 LLM 生成&#xff0c;但是面对…

fastjson1.2.68对于文件操作的分析最全

fastjson1.2.68对于文件操作的分析 前言分析复制文件写入文件清空文件读取文件分析poc拓宽场景极限环境poc优化修改再次优化poc的分析 前言 这次分析也是分析了很久&#xff0c;因为每个链子都是自己去跟着分析了的&#xff0c;然后主要是去学习了一下怎么去挖链子 分析 前面…

洛谷P1364 医院设置

P1364 医院设置 题目描述 设有一棵二叉树&#xff0c;如图&#xff1a; 其中&#xff0c;圈中的数字表示结点中居民的人口。圈边上数字表示结点编号&#xff0c;现在要求在某个结点上建立一个医院&#xff0c;使所有居民所走的路程之和为最小&#xff0c;同时约定&#xff0c…

四、基于Stage模型的应用架构设计

前面我们了解了如何构建鸿蒙应用以及开发了第一个页面&#xff0c;这只是简单的demo&#xff1b;那么如何去设计&#xff0c;从0到1搭建一个真正的应用呢 一、基本概念 1、Stage模型基本概念 Stage模型概念图 AbilityStage&#xff1a;是一个Module级别的组件容器&#xff0…