@TOC
前言:在security初体验(一)里,用户名和密码的认证都是基于内存级别的,本章主要是说security如何从db里取用户名和密码来验证的。

1.准备的sql

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`enabled` tinyint(1) NULL DEFAULT NULL,`locked` tinyint(1) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;INSERT INTO `user` VALUES (1, 'root', '$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO', 1, 0);
INSERT INTO `user` VALUES (2, 'admin', '$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO', 1, 0);
INSERT INTO `user` VALUES (3, 'tom', '$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO', 1, 0);DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;INSERT INTO `role` VALUES (1, 'db', '数据库管理员');
INSERT INTO `role` VALUES (2, 'admin', '系统管理员');
INSERT INTO `role` VALUES (3, 'user', '用户');DROP TABLE IF EXISTS `user_role_ref`;
CREATE TABLE `user_role_ref`  (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` int(11) NULL DEFAULT NULL,`role_id` int(11) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;INSERT INTO `user_role_ref` VALUES (1, 1, 1);
INSERT INTO `user_role_ref` VALUES (2, 1, 2);
INSERT INTO `user_role_ref` VALUES (3, 2, 2);
INSERT INTO `user_role_ref` VALUES (4, 3, 3);

2.pom.xml

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.yl</groupId><artifactId>security-db</artifactId><version>0.0.1-SNAPSHOT</version><name>security-db</name><description>Demo project for Spring Boot</description><properties><java.version>11</java.version></properties><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.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency></dependencies><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/min/resources</directory></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3.application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.password=root

4.securityconfig

package com.yl.securitydb.config;import com.yl.securitydb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredUserService userService;@BeanBCryptPasswordEncoder bCryptPasswordEncoder() {return new BCryptPasswordEncoder();}// 配置角色继承关系,即dba角色拥有admin角色的权限,而admin角色拥有user角色的权限,所以dba角色也拥有了user角色的权限
//    @Bean
//    RoleHierarchy roleHierarchy() {//        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
//        String hierarchy = "ROLE_db > ROLE_admin \n ROLE_admin > ROLE_user";
//        roleHierarchy.setHierarchy(hierarchy);
//        return roleHierarchy;
//    }@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 基于数据库的用户名和密码认证auth.userDetailsService(userService);}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/db/**").hasRole("db").antMatchers("/admin/**").hasRole("admin").antMatchers("/user/**").hasRole("user").anyRequest().authenticated().and().formLogin().permitAll().and().csrf().disable();}
}

5.实体类

package com.yl.securitydb.domain;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;public class User implements UserDetails {private Integer id;private String username;private String password;private Boolean enabled;private Boolean locked;private List<Role> roles;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public void setUsername(String username) {this.username = username;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {List<SimpleGrantedAuthority> list = new ArrayList<>();for (Role role : roles) {list.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));}return list;}@Overridepublic String getPassword() {return password;}@Overridepublic String getUsername() {return username;}// 账户是否未过期@Overridepublic boolean isAccountNonExpired() {return true;}// 账户是否未锁定@Overridepublic boolean isAccountNonLocked() {return !locked;}// 凭证是否未过期@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return enabled;}public void setPassword(String password) {this.password = password;}public void setEnabled(Boolean enabled) {this.enabled = enabled;}public void setLocked(Boolean locked) {this.locked = locked;}public List<Role> getRoles() {return roles;}public void setRoles(List<Role> roles) {this.roles = roles;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", enabled=" + enabled +", locked=" + locked +'}';}
}
package com.yl.securitydb.domain;import java.io.Serializable;public class Role implements Serializable {private Integer id;private String name;private String description;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}@Overridepublic String toString() {return "Role{" +"id=" + id +", name='" + name + '\'' +", description='" + description + '\'' +'}';}
}
package com.yl.securitydb.domain;import java.io.Serializable;public class UserRoleRef implements Serializable {private Integer id;private Integer userId;private Integer roleId;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}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;}@Overridepublic String toString() {return "UserRoleRef{" +"id=" + id +", userId=" + userId +", roleId=" + roleId +'}';}
}

6.mapper

package com.yl.securitydb.mapper;import com.yl.securitydb.domain.Role;
import com.yl.securitydb.domain.User;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface UserMapper {User loadUserByUsername(String username);List<Role> getRolesByUserId(Integer userId);
}

7.mapper.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.yl.securitydb.mapper.UserMapper"><select id="loadUserByUsername" resultType="com.yl.securitydb.domain.User">select * from user where username = #{username}</select><select id="getRolesByUserId" resultType="com.yl.securitydb.domain.Role">select * from role where id in (select role_id from user_role_ref where user_id = #{userId})</select></mapper>

8.service

package com.yl.securitydb.service;import com.yl.securitydb.domain.User;
import com.yl.securitydb.mapper.UserMapper;
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 UserService implements UserDetailsService {@AutowiredUserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userMapper.loadUserByUsername(username);if (user == null) {throw new UsernameNotFoundException("用户名不存在");}user.setRoles(userMapper.getRolesByUserId(user.getId()));return user;}
}

9.controller

package com.yl.securitydb.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@GetMapping("/hello")public String hello() {return "hello security";}@GetMapping("/admin/hello")public String admin() {return "hello admin";}@GetMapping("/db/hello")public String db() {return "hello db";}@GetMapping("/user/hello")public String user() {return "hello user";}
}

10.测试

1.用admin账号登录,只能访问/admin/hello接口

2.admin账号不能访问其他两个接口

11.角色继承

1.配置

2.测试
1)登录root账号发现其可以访问/user/hello,/admin/hello,/db/hello这三个接口


security基于数据库的认证(二)相关推荐

  1. Spring Security 基于数据库的认证

    介绍 之前使用的全是基于内存的认证,这里使用基于数据库的认证. 设计数据表 这里设计数据表 创建项目 这里使用Mybatis作为项目. 添加如下依赖 添加driud连接池依赖 <dependen ...

  2. security基于数据库的认证

    目的:登录用户名密码     获取到数据库中的用户 .密码以及权限,根据不同用户以及不同权限,可访问的路径权限也受到限制. 这边用一个小的案例,来体现大体的security权限思想. 1.首先先根据数 ...

  3. spring security:基于MongoDB的认证

    spring security对基于数据库的认证支持仅限于JDBC,而很多项目并非使用JDBC,比如Nosql数据库很多使用的是 Mongo Java Driver,这样就无法用默认的<jdbc ...

  4. Spring Boot安全管理—基于数据库的认证

    基于数据库的认证 1. 设计数据库表 首先设计一个基本的用户角色表,一共三张表,分别是用户表.角色表以及用户角色关联表. SET FOREIGN_KEY_CHECKS=0;-- ----------- ...

  5. Spring Security基于数据库认证用户登录

    Spring Security为我们提供了默认的登录页面,通过重写以AuthenticationManagerBuilder为参数的configure方法,我们可基于各种数据存储来认证用户,比如内存. ...

  6. (二)基于数据库的认证与授权

    环境准备 controller @RestController @RequestMapping("/api/admin") public class AdminController ...

  7. Spring Security使用数据库登录认证授权

    一.搭建项目环境 1.创建 RBAC五张表 RBAC,即基于角色的权限访问控制(Role-Based Access Control),就是用户通过角色与权限进行关联. 在这种模型中,用户与角色之间,角 ...

  8. spring security基于数据库的安全认证 配置

    创建数据库 /* Navicat MySQL Data TransferSource Server : mysql3306 Source Server Version : 50542 Source H ...

  9. 实现账号在一端登入_跟我学spring security 基于数据库实现一个基本的登入登出...

    第一章我们基于内存中的用户信息实现了一个基本的登入功能,不过实际的项目中用户信息一般都是存在数据库中的.本章我们来实现一个比较接近真实项目的登入登出,同时引入UserDetailsService的概念 ...

最新文章

  1. erlang 怎么获得socket中的属性_技术干货,python中的异步网络框架socketserver
  2. 愿将一生献宏谋——送别于敏侧记
  3. 支持将数据导出到Excel文档的时候设置单元格格式的.NET控件Spire.DataExport
  4. verilog中级别到底是什么?级别的分类是什么???
  5. Ehcache BigMemory: 摆脱GC困扰(转)
  6. 2013年新年礼物---CrossFPC 终于出来了
  7. 台式电脑键盘按键错乱_电脑键盘按键怕误触怎么办?用这款软件帮你屏蔽指定键盘按键!支持替换按键!...
  8. pg插入执行成功但是没有数据_pg_lightool基于basebackup的单表恢复和块恢复
  9. @Html.ValidationSummary()作用
  10. corosync配置与详解
  11. 使用 JS 实现页面跳转的几种方式总结,小菜一碟!
  12. android修改shell串口号,[Note] 2021-01-15 Android shell/串口中使用 wpa_cli 连接Wi-Fi
  13. linux系统如何拨号上网连接,linux系统下怎样进行拨号上网?
  14. 阅读不懂,图书之过——《大话设计模式》创作历程 (转载)
  15. 个人公众号,用于开发经验分享
  16. 6.16 实现音乐的背景播放功能 [原创iOS开发-Xcode教程]
  17. 【云原生】在 React Native 中使用 AWS Textract 实现文本提取
  18. calfcamel 的 2333
  19. 如何使用启动盘PE桌面工具安装原版win7系统?
  20. 北京老家具修复服务器,涨知识:图解古旧家具修复的六个步骤

热门文章

  1. 都要和硬件工程师“作对”吗?
  2. 二年级数学计算机教学教案,人教版二年级下册数学全册教案
  3. Windows提权流程及手法
  4. 默纳克调试说明书_默纳克NICE调试说明书修改版
  5. 对「曲线拟合」和「最小二乘法」的个人理解
  6. Excel定位功能删除空值所在行
  7. 2023 年软件文档工具,这5款可以看看!
  8. 计算机网络基础教程实训总结,实训总结
  9. js中数组的几种循环方式
  10. SNAT(源地址转换)