实现基于Spring Security的权限管理系统

实现基于Spring Security的权限管理系统

大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!

在现代Web应用中,权限管理系统是至关重要的组成部分。通过有效的权限管理,可以确保应用程序的安全性,防止未经授权的用户访问敏感数据。Spring Security是一个强大且灵活的安全框架,能够帮助我们轻松实现复杂的权限管理系统。本文将详细介绍如何使用Spring Security实现一个基于角色和权限的权限管理系统。

1. Spring Security概述

Spring Security是Spring框架的一个子项目,提供了全面的安全服务,包括身份验证和授权。其核心概念包括用户、角色和权限。用户可以拥有多个角色,每个角色可以拥有多种权限。通过Spring Security,我们可以对Web应用的访问进行细粒度控制。

2. 项目依赖

首先,我们需要在pom.xml中添加Spring Security相关的依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

3. 数据库设计

我们设计一个简单的数据库模型,包括用户、角色和权限三个实体。

package cn.juwatech.model;

import javax.persistence.*;
import java.util.Set;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "user_roles",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Role> roles;

    // getters and setters
}
package cn.juwatech.model;

import javax.persistence.*;
import java.util.Set;

@Entity
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "role_permissions",
        joinColumns = @JoinColumn(name = "role_id"),
        inverseJoinColumns = @JoinColumn(name = "permission_id")
    )
    private Set<Permission> permissions;

    // getters and setters
}
package cn.juwatech.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Permission {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    // getters and setters
}

4. 用户认证与授权

我们需要实现UserDetailsService接口来加载用户信息。

package cn.juwatech.service;

import cn.juwatech.model.User;
import cn.juwatech.repository.UserRepository;
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.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");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getAuthorities());
    }
}

5. 安全配置

配置Spring Security来处理请求的认证与授权。

package cn.juwatech.config;

import cn.juwatech.service.CustomUserDetailsService;
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.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@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()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

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

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

6. 控制器

实现简单的控制器来处理请求。

package cn.juwatech.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "home";
    }

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

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

    @GetMapping("/login")
    public String login() {
        return "login";
    }
}

7. 前端页面

创建简单的HTML页面来展示不同的视图。

home.html

<!DOCTYPE html>
<html>
<head>
    <title>Home</title>
</head>
<body>
    <h1>Welcome to the Home Page</h1>
    <a href="/user">User Page</a>
    <a href="/admin">Admin Page</a>
    <a href="/logout">Logout</a>
</body>
</html>

admin.html

<!DOCTYPE html>
<html>
<head>
    <title>Admin</title>
</head>
<body>
    <h1>Welcome to the Admin Page</h1>
    <a href="/">Home</a>
    <a href="/logout">Logout</a>
</body>
</html>

user.html

<!DOCTYPE html>
<html>
<head>
    <title>User</title>
</head>
<body>
    <h1>Welcome to the User Page</h1>
    <a href="/">Home</a>
    <a href="/logout">Logout</a>
</body>
</html>

login.html

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login Page</h1>
    <form method="post" action="/login">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username">
        <br>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password">
        <br>
        <button type="submit">Login</button>
    </form>
</body>
</html>

8. 数据初始化

使用data.sql文件初始化数据库。

INSERT INTO user (username, password) VALUES ('admin', '$2a$10$WzAqEJdKzHQ9E.o/qT41f.J.oPjDNCRK0AejsbTiKCN.p6qMjr8ru'); -- 密码: password
INSERT INTO user (username, password) VALUES ('user', '$2a$10$WzAqEJdKzHQ9E.o/qT41f.J.oPjDNCRK0AejsbTiKCN.p6qMjr8ru'); -- 密码: password

INSERT INTO role (name) VALUES ('ROLE_ADMIN');
INSERT INTO role (name) VALUES ('ROLE_USER');

INSERT INTO user_roles (user_id, role_id) VALUES (1, 1); -- admin -> ROLE_ADMIN
INSERT INTO user_roles (user_id, role_id) VALUES (2, 2); -- user -> ROLE_USER

总结

本文详细介绍了如何使用Spring Security实现一个基于角色和权限的权限管理系统。从依赖配置、数据库设计、用户认证与授权,到安全配置和前端页面展示,全面覆盖了一个完整权限管理系统的实现步骤。

微赚淘客系统3.0小编出品,必属精品!

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

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

相关文章

golang结合neo4j实现权限功能设计

neo4j 是非关系型数据库之图形数据库&#xff0c;这里不再赘述。 传统关系数据库基于rbac实现权限, user ---- role ------permission,加上中间表共5张表。 如果再添上部门的概念&#xff1a;用户属于部门&#xff0c;部门拥有 角色&#xff0c;则又多了一层&#xff1a; user-…

WPF UI 界面布局 魔术棒 文字笔记识别 技能提升 布局功能扩展与自定义 继承Panel的对象,测量与排列 系列七

应用开发第一步 功能分类&#xff1a;页面上的功能区域划分。。。。需求分析 业务逻辑 数据流 功能模块 UI/UX 编码 测试 发布 功能开发与布局 不用显式的方式设定元素的尺寸 不使用屏幕坐标来指定位置 Grid 功能最强大&#xff0c;布局最灵活的容器…

代码提交错分支了怎么办?

你有么有遇到过正在开发的代码&#xff0c;提交到生产环境的分支去&#xff0c;遇到这种情况怎么办&#xff1f; 问题重现&#xff1a; 这段注释// AAAAAAAAAAA 本来应该写在dev分支的&#xff0c;现在提交并push到master分支了 现在第一步&#xff0c;撤回提交 第二步&…

第五届机械工程与智能制造国际学术会议(MEIM 2024,7月26-28)

第五届机械工程与智能制造国际学术会议(MEIM 2024) 计划2024年7月26-28日在中国辽宁锦州隆重举行。本次会议由辽宁理工学院主办。 会议主要围绕机械工程与智能制造等研究领域展开讨论&#xff0c;旨在为从事机械工程与智能制造研究的专家学者、程技术人员、技术研发人员提供一个…

Midjourney 如何使用参考图像来提升图像的准确性和相似度?

🧙🏼图像提示 🧙🏼‍♂️ 您可以使用图像作为提示的一部分来影响作业的构图、样式和颜色。图像提示可以单独使用,也可以与文本提示一起使用 - 尝试组合具有不同样式的图像以获得最令人兴奋的结果。 🛠️实际图像提示操作步骤 点击加号按钮,双击上传文件,把小黄猫…

SwiftUI 6.0(iOS 18.0)滚动视图新增的滚动阶段(Scroll Phase)监听功能趣谈

何曾几时&#xff0c;在 SwiftUI 开发中的秃头小码农们迫切需要一种能够读取当前滚动状态的方法。 在过去&#xff0c;他们往往需要借助于 UIKit 的神秘力量。不过这一切在 SwiftUI 6.0 中已成“沧海桑田”。 在本篇博文中&#xff0c;您将学到如下内容&#xff1a; 1. Scroll…

Anubi WebKey开启去中心化数字革命的新纪元

随着技术的飞速发展&#xff0c;Web3正在重新定义未来互联网的架构&#xff0c;标志着从集中式控制向去中心化自主的历史性转变。在这场全球性的技术演变中&#xff0c;Anubi WebKey不仅仅是一款前沿的智能设备&#xff0c;它代表的是一种划时代的技术革命&#xff0c;一个重塑…

24.【C语言】getchar putchar的使用

1.基本作用 用户输入字符&#xff0c;getchar()获取字符&#xff08;含\n:即键入的Enter&#xff09;&#xff08;字符本质上是以ASCII值或EOF&#xff08;-1&#xff09;存储的&#xff09;&#xff08;与scanf有区别&#xff09; putchar() 打印字符&#xff08;把得到的A…

图像畸变矫正与透视变换

图像畸变矫正与透视变换 Halcon自动生成的圆形棋盘格Halcon透视变换 Halcon自动生成的圆形棋盘格 示例程序&#xff1a; *生成棋圆形棋盘格 行 列 直径 直径/距离比值 gen_caltab (12, 9, 0.002, 0.5, caltab_12X9.descr, caltab.ps) *生成相机参数 焦距 畸变系数 X解析度 Y解…

计算云服务1

前言 一直以来&#xff0c;计算资源都是整个企业业务系统发展所需的大动脉&#xff0c;没有计算资源&#xff0c;企业业务就无法正常运行。在云计算的时代里&#xff0c;计算服务也是云服务中的第一大类服务&#xff0c;计算资源的重要性由此可见。本章&#xff0c;我们将带领…

【数据结构】常见四类排序算法

1. 插入排序 1.1基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。实际中我们…

HTML5+JavaScript单词游戏

HTML5 JavaScript单词游戏 数据字典格式&#xff1a;每行一个 单词 &#xff0c;单词和解释用空格分隔&#xff0c;如 a art.一(个)&#xff1b;每一(个) ability n.能力&#xff1b;能耐&#xff0c;本领 able a.有能力的&#xff1b;出色的 baby n.婴儿&#xff1b;孩子…

NET程序开发可能会用到的一些资料文档

NET程序开发使用的一些资料文件&#xff0c;NET高级调试&#xff0c;NET关键技术深入解析&#xff0c;WPF专业编程指南&#xff0c;程序员求职攻略&#xff0c;WPF编程宝典等。 下载链接&#xff1a;https://download.csdn.net/download/qq_43307934/89518582

Python入门 2024/7/6

目录 数据容器入门 列表的定义语法 基本语法 嵌套列表 ​编辑 列表的下表索引 ​编辑 列表的常用操作 列表的常见方法 查找元素的下标 修改下标索引的值 插入元素 追加元素 追加一批元素 删除元素 删除某元素在列表中的第一个匹配项 清空列表内容 统计元素在…

【Unity URP】通过代码动态添加URP渲染通道RendererFeature

URP的渲染通道RendererFeature可以很方便的实现一些渲染问题,比如渲染顺序问题,遮挡后的材质替换等等。 那么我们如何通过代码来动态添加和修改呢? 首先我们需要获取到当前的URP配置文件,在对配置文件进行添加 1.通过反射获取当前UniversalRendererData 我们通过Graphic…

Linux:文件系统与日志分析

一、block与inode 1.1、概述 文件是存储在硬盘上的&#xff0c;硬盘的最小存储单位叫做“扇区”(sector)&#xff0c;每个扇区存储512字节。 一般连续八个扇区组成一个"块”(block)&#xff0c;一个块是4K大小&#xff0c;是文件存取的最小单位。 文件数据包括实际数据…

【数据分享】国家级旅游休闲街区数据(Excel/Shp格式/免费获取)

之前我们分享过从我国文化和旅游部官网整理的2018-2023年我国50个重点旅游城市星级饭店季度经营状况数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01;文化和旅游部官网上也分享有很多与旅游相关的常用数据&#xff0c;我们基于官网发布的名单文件整理得到全国…

.net 调用海康SDK的跨平台解决方案

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔序言 上2篇海康SDK使用以及常见的坑…

【JavaEE精炼宝库】文件操作(1)——基本知识 | 操作文件——打开实用性编程的大门

目录 一、文件的基本知识1.1 文件的基本概念&#xff1a;1.2 树型结构组织和目录&#xff1a;1.3 文件路径&#xff08;Path&#xff09;&#xff1a;1.4 二进制文件 VS 文本文件&#xff1a;1.5 其它&#xff1a; 二、Java 操作文件2.1 方法说明&#xff1a;2.2 使用演示&…

第十五章 Nest Pipe(内置及自定义)

NestJS的Pipe是一个用于数据转换和验证的特殊装饰器。Pipe可以应用于控制器&#xff08;Controller&#xff09;的处理方法&#xff08;Handler&#xff09;和中间件&#xff08;Middleware&#xff09;&#xff0c;用于处理传入的数据。它可以用来转换和验证数据&#xff0c;确…