4. Spring Boot Security角色管理持久化实现

2023-11-19

1.概述,

在第三章里大家学会了怎么初步使用Spring Boot 结合Spring Security来实现权限控制和角色管理,  但是我们发现无论是使用那种方式角色管理和权限控制全部是在 xml中或则 配置类中写的, 没有实现持久化, 本次就为大家讲解怎么实现.本小结为大家讲 用户角色管理的实现,  至于权限控制来下一个小结会讲.

2.表和数据

这里写图片描述

PDM文件路径: https://github.com/masterjyq/Spring-Boot.git

数据

insert into sys_user_demo (user_id,user_name, user_passwd) values (1,'admin', 'admin');
insert into sys_user_demo (user_id,user_name, user_passwd) values (2,'abel', 'abel');

insert into sys_role_demo(role_id,role_name) values(1,'ROLE_ADMIN');
insert into sys_role_demo(role_id,role_name) values(2,'ROLE_USER');

insert into user_role_demo(user_role_id,role_id,user_id) values(1,1,1);
insert into user_role_demo(user_role_id,role_id,user_id) values(2,2,2);

3.创建PO

这里写图片描述

SysUserDemo.java

package com.hand.sys.model;

/**
 * Created by JQY on 2017/12/3.
 */
public class SysUserDemo
{
    private  Integer userId;
    private  String  userName;
    private  String  userPasswd;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPasswd() {
        return userPasswd;
    }

    public void setUserPasswd(String userPasswd) {
        this.userPasswd = userPasswd;
    }
}

SysRoleDemo.java

package com.hand.sys.model;

/**
 * Created by JQY on 2017/12/3.
 */
public class SysRoleDemo
{
    private Integer roleId;
    private  String roleName;

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
}

UserRoleDemo.java

package com.hand.sys.model;

/**
 * Created by JQY on 2017/12/3.
 */
public class UserRoleDemo
{
    private  Integer userRoleId;
    private  Integer userId;
    private  Integer roleId;

    public Integer getUserRoleId() {
        return userRoleId;
    }

    public void setUserRoleId(Integer userRoleId) {
        this.userRoleId = userRoleId;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
}

4. 处理登录要用的类

4.1协助处理登录的DAO 和Mapper

UserDao.java

package com.hand.sys.dao;

import com.hand.sys.model.SysUserDemo;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * Created by JQY on 2017/12/3.
 */
@Repository
@Mapper
public interface UserDao
{
    public List<Map<String,String>> findRole(String name);

}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.hand.sys.dao.UserDao" >

    <!--khm 是配置文件的别名,本体是KeyHashMap-->
    <select id="findRole"  resultType="khm" parameterType="String">
        select *
        from SYS_USER_DEMO u, SYS_ROLE_DEMO r,USER_ROLE_DEMO hr
        WHERE  u.user_id (+) = hr.USER_ID
        and    r.ROLE_ID (+)= hr.ROLE_ID
        and    u.USER_NAME = #{userName}
    </select>
</mapper>

4.2协助处理登录service

CustomUserService.java

package com.hand.security;

import com.hand.sys.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * Created by JQY on 2017/12/3.
 */
@Service
public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口

    @Autowired
    private  UserDao userDao;

    //重写loadUserByUsername 方法获得 userdetails 类型用户
    @Override
    public UserDetails loadUserByUsername(String name) {

        List<Map<String,String>> user = userDao.findRole(name);
        if(user.get(0) == null){
            throw new UsernameNotFoundException("用户名不存在");
        }
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //来遍历用户角色添加到缓存
        for(Map<String,String> role : user)
        {
            authorities.add(new SimpleGrantedAuthority(role.get("roleName")));
            System.out.println(role.get("roleName"));
        }
        return new org.springframework.security.core.userdetails.User(user.get(0).get("userName"),
                user.get(0).get("userPasswd"), authorities); //返回用户名密码, 来和前端传来的对比
    }
}

5.写配置注入刚刚的service

此处还是给大家讲了两种配置方式,配置类和 xml  建议 xml, 两种的切换使用见第三章

5.1 配置类的方式, 修改第三章的配置类

WebSecurityConfig.java

package com.hand.security;

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.core.userdetails.UserDetailsService;

/**
 * Created by JQY on 2017/11/21.
 * 去除注解暂时废弃
 *
 */
//@Configuration
//@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/styles/**","/scripts/**").permitAll() //指定那些URL不要被保护
                .antMatchers("/res/list").hasRole("USER") //ROLE_ 去除  一定要在 /** 前面才有作用
                .antMatchers("/**").hasRole("ADMIN")  //此处要把 ROLE_ 去除
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login") //登录的时候你要跳转到哪里
                .failureUrl("/login?error") //失败页面
                .permitAll() //登录任意访问
                .and()
                .rememberMe() //rememberMe
                .and() //注销行为任意访问
                .logout()
                .permitAll()
                .and()
                .csrf() //关闭csrf 不然不支持post
                .disable();

    }

    @Bean
    UserDetailsService customUserService(){ //注册UserDetailsService 的bean
        return new CustomUserService(); //注入刚刚写的service
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(customUserService()); //user Details Service验证
        /*auth
                .inMemoryAuthentication()
                //用户名密码和角色
                .withUser("jyq").password("123456").roles("USER");*/
    }
}

5.2 xml的配置

applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/security
                           http://www.springframework.org/schema/security/spring-security-4.2.xsd">

    <!--拦截器过滤配置-->
    <sec:http auto-config="true">
        <!--开启remember-me-->
        <sec:remember-me />
        <!--关闭csrf-->
        <sec:csrf disabled="true"/>
        <!--静态资源的URL-->
        <sec:intercept-url pattern="/scripts/**" access="hasRole('ROLE_ANONYMOUS')"/>
        <sec:intercept-url pattern="/styles/**" access="hasRole('ROLE_ANONYMOUS')"/>

        <!--登录界面不要拦截-->
        <sec:intercept-url pattern="/login" access="hasRole('ROLE_ANONYMOUS')"/>

        <!--具体页面拦截规则-->
        <sec:intercept-url pattern="/res/list" access="hasRole('ROLE_USER')"/>
        <sec:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"/>

        <!--自定义页面-->
        <sec:form-login login-page="/login"   authentication-failure-url="/login?error"
                        default-target-url="/login"/>

    </sec:http>

    <!--注入BEAN-->
    <bean id="customUserService" class="com.hand.security.CustomUserService">

    </bean>

    <!--配置用户-->
    <sec:authentication-manager>
        <sec:authentication-provider user-service-ref="customUserService">
            <!--<sec:user-service >
                <sec:user name="jyq" password="123456" authorities="ROLE_ADMIN"/>
            </sec:user-service>-->
        </sec:authentication-provider>
    </sec:authentication-manager>
</beans>

6. 我们再写一个给 user 角色的页面 我们配置的是res/list 那就写个测试页面

6.1写页面

这里写图片描述

role.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>欢迎角色USER</h1>


<form th:action="@{/logout}" method="post">
    <input type="submit" value="注销"/>
</form>
</body>
</html>

6.2修改controller 加上映射

ResourceTableController.java

package com.hand.demo.controller;

import com.hand.demo.model.ResouceTable;
import com.hand.demo.service.ResourceTableService;
import com.jyq.utils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Map;

/**
 * Created by JYQ on 2017/11/13.
 */
@Controller
@RequestMapping("res")
public class ResourceTableController {

    @Autowired
    private ResourceTableService resourceTableService;

    @RequestMapping("query")
    public String query(Model model, ResouceTable resouceTable)
    {
       model.addAttribute("res",resourceTableService.query(resouceTable));
       return "resource_table";
    }

    @RequestMapping("list")
    public String list(Model model, ResouceTable resouceTable)
    {
        model.addAttribute("res",resourceTableService.query(resouceTable));
        return "demo/role";
    }


}

7测试

先用 admin访问 http://localhost:8888/demo/res/queryhttp://localhost:8888/demo/res/list
会发现都可以访问

但是用 user用户只可以访问http://localhost:8888/demo/res/list
访问http://localhost:8888/demo/res/query会显示没有权限

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

4. Spring Boot Security角色管理持久化实现 的相关文章

随机推荐

  • 用pycharm+flask 建立项目以后运行出现ImportError: No module named flask-login问题

    出现此问题 一般情况下 打开CMD输入 pip install flask login 然后 在cmd中输入命令 pip list 查看目前已安装的的模板 在此时 如果你继续运行项目 有可能会发现问题已经解决 但是也有可能会发现问题依然存在
  • Rust中的iter(), into_iter(), iter_mut()

    在Rust中 iter into iter iter mut 都是用于在集合类型上创建迭代器的方法 这三个方法各有不同 下面一一进行介绍 iter iter 方法创建一个不可变的引用迭代器 当你只想读取集合中的元素 而不想改变它们或消耗集合
  • C++57个入门知识点_27 继承的概念(类的组合关系:将一个类的对象作为另外一个类的成员;类的组合关系的访问;继承的概念:A类是B的儿子;A被称为子类,B被称为父类或者A被称为派生类,B被称为基类)

    我们知道类有三大特性 封装 继承和多态 封装在前面已经介绍完 本篇开始将会介绍继承 继承是在封装基础上的扩展 也是多态的一个承接 总结 类的组合关系 将一个类的对象作为另外一个类的成员 Class CStudent public priva
  • maven常用命令大全(附详细解释)

    1 常用打包命令 mvn clean package Dmaven test skip true 跳过单测打包 mvn clean install Dmaven test skip true 跳过单测打包 并把打好的包上传到本地仓库 mvn
  • MCU震荡电路的晶振边的22pf电容的作用

    振荡电路用于实时时钟RTC 对于这种振荡电路只能用32 768KHZ 的晶体 晶体被连接在OSC3 与OSC4 之间而且为了获得稳定的频率必须外加两个带外部电阻的电容以构成振荡电路 32 768KHZ的时钟晶振产生的振荡信号经过石英钟内部分
  • (3)numpy数组的索引和切片操作

    在开始之前 先导入numpy第三方包 import numpy as np 索引 谈到索引 我们就应该想到 在python语言中 是如何对列表进行索引的 接下来将会对python列表索引和numpy数组索引进行比较 先定义一个numpy数组
  • 查看linux中的TCP连接数

    一 查看哪些IP连接本机 netstat an 二 查看TCP连接数 1 统计80端口连接数 netstat nat grep i 80 wc l 2 统计httpd协议连接数 ps ef grep httpd wc l 3 统计已连接上的
  • 一招秒开GitHub,永久解决!

    步骤 目录 步骤 1 打开电脑 进入如下的路径 2 将hosts 复制到桌面 3 把hosts文件移动到桌面后etc文件夹下的hosts文件不存在 已经被移动到桌面了 4 在移到桌面的hosts文件里面进行修改 5 再把修改好的hosts文
  • mysql tomcat 自动重连_Java开发网 - tomcat连接池支持重新连接数据库吗?

    Posted by pigengler Posted on 2006 04 20 15 23 我做了一个测试 程序使用tomcat的连接池 factory org apache commons dbcp BasicDataSourceFac
  • 微信api ----统一下单

    应用场景 除被扫支付场景以外 商户系统先调用该接口在微信支付服务后台生成预支付交易单 返回正确的预支付交易回话标识后再按扫码 JSAPI APP等不同场景生成交易串调起支付 状态机 支付状态转变如下 接口链接 URL地址 https api
  • pandas中的data.corr()函数方法说明及使用

    数据相关性分析中 经常用到data corr 函数 data corr 表示了data中的两个变量之间的相关性 取值范围为 1 1 取值接近 1 表示反相关 类似反比例函数 取值接近1 表正相关 DataFrame corr 函数使用说明如
  • 国际版阿里云/腾讯云:阿里云流量包是用来做什么

    阿里云流量包是用来做什么 阿里云同享流量包是一种通用流量套餐 同享流量包具有多地域和多产品流量抵扣的优势 同享流量包不仅能够抵扣云服务器ECS发生的流量 还能够抵扣弹性公网IP和负载均衡SLB发生的流量 同享流量包掩盖产品规模广 同享流量包
  • Qt 设置:两个窗口位置重合

    目录 Qt 设置 两个窗口位置重合 QT向界面中嵌套新的界面 QT向界面中嵌套新的界面 https www cnblogs com bob jianfeng p 11609012 html 第一步 先进入ui编辑界面 加入一个水平或者垂直的
  • 数据预处理与特征工程—10.图像切割与特征提取

    文章目录 引言 一 图像切割 二 特征提取 1 各阶颜色矩的计算公式 三 python实现 水质图像数据 百度网盘链接提取码 1234 引言 本文以水质图像为例 进行图像切割与特征提取 一 图像切割 一般情况下 采集到的水样图片包含盛水容器
  • 深入研究C++多态(虚函数和虚继承)

    文章目录 多态的引入 虚函数表 几种常见继承关系中的类内存分布 单继承 多继承 菱形继承 总结 作者 狗子孙 链接 https www jianshu com p 02183498a2c2 来源 简书 简书著作权归作者所有 任何形式的转载都
  • 如何彻底删除JetBrains系列软件教程

    mac安装JetBrains系列软件后 如果JetBrains系列软件出了问题需要重新安装 有时候软件删除重装后 JetBrains系列软件仍然会打不开的问题 很是困扰 接下来为您带来了mac上如何彻底删除IntelliJ IDEA等软件的
  • Char.IsDigit与Char.IsNumber的区别

    需要判断Char是否为数字 查看了下MSDN 发现有三种方法 Char IsDigit aChar 指示指定字符串中位于指定位置处的字符是否属于十进制数字类别 Char IsNumber aChar 指示指定字符串中位于指定位置的字符是否属
  • redis cluster知识

    一 架构 Redis Cluster使用 Slot 的概念 作为一个KV系统 它把每个key的值hash成0 16383之间的一个数 这个hash值被用来确定对应的数据存储在哪个节点中 集群中的每个节点都存储了一份类似路由表的东西 描述每个
  • 你知道bdsm吗

    是的 我知道 BDSM BDSM 是一种性癖好 通常指一组相关的性癖好 包括 较强的角色扮演 较轻的或较重的身体触摸 以及在性活动中的安全词 BDSM 也可以包括授权和自我控制 以及建立信任和良好的沟通 BDSM 可能涉及各种形式的挑逗 包
  • 4. Spring Boot Security角色管理持久化实现

    1 概述 在第三章里大家学会了怎么初步使用Spring Boot 结合Spring Security来实现权限控制和角色管理 但是我们发现无论是使用那种方式角色管理和权限控制全部是在 xml中或则 配置类中写的 没有实现持久化 本次就为大家