springboot整合springsecurity,从数据库中认证

概述:springsecurity这个东西太容易忘了,这里写点东西,避免忘掉

目录

第一步:引入依赖

第二步:创建user表

第三步:创建一个用户实体类(User)和一个用于访问用户数据的Repository接口

第四步:创建一个实现UserDetailsService接口的自定义用户详情服务类,用于从数据库中加载用户信息。

第五步:创建一个配置类来配置Spring Security。

第六步:创建一个简单的控制器类用于测试

第七步:编写一个简单的数据库初始化器类用于初始化用户信息

运行项目测试查看结果


第一步:引入依赖

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.cyl</groupId>
    <artifactId>spaceTutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Send</name>
    <description>Send</description>
    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.7.13</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring Boot Starter Data JPA -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- Spring Boot Starter Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- MySQL Connector Java -->
         <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>


    </dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <compilerArgs>
                    <arg>--enable-preview</arg>
                    <arg>--add-modules=jdk.incubator.vector</arg>
                </compilerArgs>
                <compilerVersion>17</compilerVersion>
                <source>17</source>
                <target>17</target>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

第二步:创建user表

CREATE TABLE users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(100) NOT NULL,
    password VARCHAR(255) NOT NULL,
    enabled TINYINT(1) DEFAULT 1,
    role VARCHAR(50)
);

第三步:创建一个用户实体类(User)和一个用于访问用户数据的Repository接口

User类

package org.cyl.spaceutils.pojo;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "users")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "username")
    private String username;
    
    @Column(name = "password")
    private String password;
    
    @Column(name = "enabled")
    private boolean enabled;
    
    @Column(name = "role")
    private String role;

    // Getters and setters

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

Repository接口

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

第四步:创建一个实现UserDetailsService接口的自定义用户详情服务类,用于从数据库中加载用户信息。

实现类

package org.cyl.spaceutils.service;

import org.cyl.spaceutils.pojo.User;
import org.cyl.spaceutils.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
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.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
        return new org.springframework.security.core.userdetails.User(
                user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true,
                AuthorityUtils.createAuthorityList(user.getRole())
        );
    }
}

第五步:创建一个配置类来配置Spring Security。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout().permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

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

第六步:创建一个简单的控制器类用于测试

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "Welcome to the home page!";
    }

    @GetMapping("/user")
    public String user() {
        return "Welcome user!";
    }

    @GetMapping("/admin")
    public String admin() {
        return "Welcome admin!";
    }
}

第七步:编写一个简单的数据库初始化器类用于初始化用户信息

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component
public class DatabaseInitializer implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void run(String... args) throws Exception {
        User user = new User();
        user.setUsername("user");
        user.setPassword(passwordEncoder.encode("password"));
        user.setRole("ROLE_USER");
        userRepository.save(user);

        User admin = new User();
        admin.setUsername("admin");
        admin.setPassword(passwordEncoder.encode("admin"));
        admin.setRole("ROLE_ADMIN");
        userRepository.save(admin);
    }
}

运行项目测试查看结果

启动时会增加数据到mysql里面

以ROLE_USER的身份登录

现在登录可能会出现用户被禁用的情况,将enabled设置为1即可

现在用admin账号登录

然后访问/user,出现不能访问,即可

访问/admin,查看

然后用user用户登录,记得先退出

访问/admin,出现无法访问的情况

访问/user,出现访问正常的情况

搞定

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文教会你SpringBoot是如何启动的

SpringBoot启动流程分析 流程图 源码剖析 运行Application.run()方法 我们在创建好一个 SpringBoot 程序之后&#xff0c;肯定会包含一个类&#xff1a;xxxApplication&#xff0c;我们也是通过这个类来启动我们的程序的&#xff08;梦开始的地方&#xff09;&#xff0c;而…

【超详细图文讲解】如何利用VMware创建CentOS虚拟机(包括如何更改网络设置 + 远程访问虚拟机方法)

文章目录 前言1. 准备相关软件环境1.1 获取 ISO 镜像包1.2 VMware 的安装 2. 使用 VMware 安装 CentOS3. 初始化虚拟机4. 虚拟机网络的设置4.1 虚拟机的三种网络连接模式桥接模式NAT 模式仅主机模式 4.2 如何更改网络设置 5. 远程访问虚拟机的方法5.1 使用 cmd 进行访问5.2 使用…

LSS (Lift, Splat, Shoot)

项目主页 https://nv-tlabs.github.io/lift-splat-shoot 图1&#xff1a;本文提出一种模型&#xff0c;给定多视角相机数据 (左)&#xff0c; 直接在鸟瞰图 (BEV) 坐标系(右)中推理语义。我们展示了车辆分割 (蓝色)&#xff0c;可驾驶区域 (橙色) 和车道分割 (绿色) 的结果。然…

外包干了28天,技术退步明显......

说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入深圳某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&a…

<DFS剪枝>数字王国之军训排队

DFS剪枝 其实就是将搜索过程一些不必要的部分直接剔除掉。 剪枝是回溯法的一种重要优化手段&#xff0c;往往需要先写一个暴力搜索&#xff0c;然后找到某些特殊的数学关系&#xff0c;或者逻辑关系&#xff0c;通过它们的约束让搜索树尽可能浅而小&#xff0c;从而达到降低时间…

程序员在公司学习新项目的5步法:

1 了解业务 - 系统所在行业&#xff1f; - 系统是做什么的&#xff1f; - 系统主要面向的人群是谁&#xff1f; - 主要提供了哪些功能&#xff1f; - 系统设计的关键业务流程是什么样的&#xff1f; - 项目面临的挑战是什么&#xff1f; - 项目未来规划是什么&#xff1f; 2 …

HarmonyOS(鸿蒙)快速入门

一:下载开发工具 鸿蒙的开发工具叫DevEco 下载点击 其他部分都一直next 就行,这个页面出现的install 建议都点击install 然后单独选择安装目录 可能存在的问题 就是之前安装nodejs&#xff08;比如自己开发web或者RN等情况&#xff09;版本低 等情况 所以建议你单独安装一次 …

c语言商品库存管理系统

定制魏:QTWZPW,获取更多源码等 目录 题目 功能概述 数据结构 用户界面 ​编辑 主要函数 数据存储 完整代码 总结 题目 实现一个商品库存管理系统,可以对商品进行入库、出库、删除、修改、查询以及显示所有商品信息的操作。 功能概述 系统包含以下主要功能: 商品…

Web基础06-AJAX,Axios,JSON数据

目录 一、AJAX 1.概述 2.主要作用 3.快速入门 4.AJAX的优缺点 &#xff08;1&#xff09;优点 &#xff08;2&#xff09;缺点 5.同源策略 二、Axios 1.概述 2.快速入门 3.请求方式别名 三、JSON 1.概述 2.主要作用 3.基础语法 4.JSON数据转换 &#xff08;1…

【MLLM+轻量多模态模型】24.02.Bunny-v1.0-2B-zh: 轻量级多模态语言模型 (效果一般)

24.02 北京人工智能研究院&#xff08;BAAI&#xff09;提出以数据为中心的轻量级多模态模型 arxiv论文&#xff1a;2402.Efficient Multimodal Learning from Data-centric Perspective 代码&#xff1a;https://github.com/BAAI-DCAI/Bunny 在线运行&#xff1a;https://wis…

day6 3/18

2.试编程&#xff1a; 封装一个动物的基类&#xff0c;类中有私有成员&#xff1a;姓名&#xff0c;颜色&#xff0c;指针成员年纪 再封装一个狗这样类&#xff0c;共有继承于动物类&#xff0c;自己拓展的私有成员有&#xff1a;指针成员&#xff1a;腿的个数&#xff08;整…

【JavaEE -- 多线程进阶 - 面试重点】

多线程进阶 1. 常见锁策略1.1 乐观锁和悲观锁1.2 轻量级锁和重量级锁1.3 自旋锁和挂起等待锁synchronized具有自适应能力1.4 普通互斥锁和读写锁1.5 公平锁和非公平锁1.6 可重入锁和不可重入锁 2. Synchronized原理&#xff08;特点、加锁过程、自适应&#xff09;2.1 Synchron…

数据结构(三)——栈

三、栈、队列和数组 3.1 栈 3.1.1 栈的基本概念 线性表是具有相同数据类型的n&#xff08;n≥0&#xff09;个数据元素的有限 序列&#xff0c;其中n为表长&#xff0c;当n 0时线 性表是一个空表。若用L命名线性表&#xff0c;则其一般表示为 L (a1, a2, … , ai , ai1, ……

【STL源码剖析】【2、空间配置器——allocator】

文章目录 1、什么是空间配置器&#xff1f;1.1设计一个简单的空间配置器&#xff0c;JJ::allocator 2、具备次配置力( sub-allocation)的 SGI 空间配置器2.1 什么是次配置力2.2 SGI标准的空间配置器&#xff0c;std::allocator2.2 SGI特殊的空间配置器&#xff0c;std::alloc2.…

ARM汇编与逆向工程 蓝狐卷 基础知识

文章目录 前言内容简介作者简介译者简介目录 前言 与传统的CISC&#xff08;Complex Instruction Set Computer&#xff0c;复杂指令集计算机&#xff09;架构相比&#xff0c;Arm架构的指令集更加简洁明了&#xff0c;指令执行效率更高&#xff0c;能够在更低的功耗下完成同样…

13 秒插入 30 万条数据,这才是 Java 批量插入正确的姿势!

本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证 实体类、mapper和配置文件定义 User实体 mapper接口 mapper.xml文件 jdbc.properties sqlMapConfig.xml 不分批次直接梭哈 循环逐条插入 MyBatis实现插入30万条数据 J…

python redis中blpop和lpop的区别

python redis中lpop()方法是获取并删除左边第一个对象。 def lpop(self,name: str,count: Optional[int] None,) -> Union[Awaitable[Union[str, List, None]], Union[str, List, None]]:"""Removes and returns the first elements of the list name.By de…

2258: 【搜索】【广度优先】最少转弯问题

题目描述 给出一张地图&#xff0c;这张地图被分为nm&#xff08;n,m<100&#xff09;个方块&#xff0c;任何一个方块不是平地就是高山。平地可以通过&#xff0c;高山则不能。现在你处在地图的&#xff08;x1,y1&#xff09;这块平地&#xff0c;问&#xff1a;你至少需要…

Vulnhub - Morpheus

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog Morpheus 靶机下载地址&#xff1a;Matrix-Breakout: 2 Morpheus ~ VulnHub 0x01 信息收集 Nmap扫描…

Spring学习记录

为什么要学Spring&#xff1f; 在回答这个问题时&#xff0c;我们先来看看现在的Java程序是如何实现的&#xff0c;以最简单的服务层与持久层为例&#xff0c;其遵循接口与具体实现类的这种方式&#xff1a; Service层接口&#xff1a;BookService.java package service; pu…