SpringSecurity结合数据库表实现权限认证
SpringSecurity结合数据表实现权限认证:
下面的案例是在SpringBoot框架实现的:
步骤一:准备数据库表 以下是五张表的脚本
### 用户表
create table Sys_User
(
id int primary key auto_increment,
username varchar(32),
password varchar(32)
); ###角色表
create table Sys_Role
(
id int primary key auto_increment,
name varchar(32)
); ###权限表
create table Sys_Permission
(
id int primary key auto_increment,
name varchar(32),
description varchar(256),
url varchar(256),
pid int
); ###用户角色表
create table Sys_user_role
(
id int primary key auto_increment,
sys_user_id int,
sys_role_id int
); ###角色权限表
create table Sys_role_permission
(
id int primary key auto_increment,
role_id int,
permission_id int
); insert into SYS_USER(id,username,password) values(1,'admin','admin');
insert into SYS_USER(id,username,password) values(2,'abel','abel'); insert into SYS_ROLE(id,name) values(1,'ROLE_ADMIN');
insert into SYS_ROLE(id,name) values(2,'ROLE_USER'); insert into SYS_USER_ROLE(SYS_USER_ID,SYS_ROLE_ID) values(1,1);
insert into SYS_USER_ROLE(SYS_USER_ID,SYS_ROLE_ID) values(2,2); BEGIN;
INSERT INTO `Sys_permission` VALUES('1','ROLE_HOME','home','/',null),('2','ROLE_ADMIN','ABel','admin',null);
COMMIT; BEGIN;
INSERT INTO `Sys_role_permission` VALUES('1','1','1'),('2','1','2'),('3','2','1');
COMMIT; 步骤二:
//1.1 application的配置
spring.datasource.url=jdbc:mysql://localhost:3306/y2156
spring.datasource.username=root
spring.datasource.password=55163
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.max-active = 20
spring.datasource.max-idle = 8
spring.datasource.min-idle=8
spring.datasource.initial-sixe=10 ######Spring jpa的配置信息
spring.jpa.database=MYSQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect server.port=8080 cn.happy.name = weilengdeyu ###es的相关配置
spring.data.elasticsearch.cluster-nodes=localhost:9300
spring.data.elasticsearch.properties.transport.tcp.connect_timeout=5s ##模板引擎的配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.cache = false
spring.thymeleaf.mode=HTML5 ###让配置文件找到mapping下的小配置文件
mybatis.mapper-locations=classpath:mapping/*.xml
###别名设置
mybatis.type-aliases-package=cn.happy.entity //1.2 在pom.xml中引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency> <!--thymeleaf和springsecurity整合的依赖-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency> <!--thymeleaf 新的模板引擎,比jsp要出色-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
步骤三:准备ui层
// 1.1. login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录</title>
<script type="text/javascript" th:src="@{/js/jquery-3.3.1.js}"></script>
<script type="text/javascript"> </script>
</head>
<body>
<div>
<form th:action="@{/login}" method="post">
<h2>请登录</h2>
用户名:<input name="username" type="text"/><br/>
密码:<input name="password" type="password"/><br/>
<input type="submit" value="登录"/><br/>
<div th:if="${loginError}"></div>
<div th:text="${errorMsg}"></div>
</form>
</div>
</body>
</html> //1.2 index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head>
<meta charset="UTF-8">
<title>博客系统</title>
<script type="text/javascript" th:src="@{/js/jquery-3.3.1.js}"></script>
<script type="text/javascript"> </script>
</head>
<body>
<div>
<!--authorize:认证,授权-->
<div sec:authorize="isAuthenticated()">
<p>登录的用户名为:<span sec:authentication="name"></span></p>
<p>登录的权限为:<span sec:authentication="principal.authorities"></span></p>
</div>
</div>
</body>
</html> 步骤四: 在entity层创建实体类
// 1.1 SysUser类
public class SysUser {
private Integer id;
private String username;
private String password; public Integer getId() {
return id;
} public void setId(Integer 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;
}
} //1.2. Permission 类
public class Permission {
private int id;
//权限名称
private String name;
//权限描述
private String description;
//授权链接
private String url;
//父节点id
private int pid; public int getId() {
return id;
} public void setId(int 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;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public int getPid() {
return pid;
} public void setPid(int pid) {
this.pid = pid;
}
} 步骤五:
在dao层创建需要的接口
//1.1 创建IUserDAO
import cn.happy.entity.SysUser;
public interface IUserDAO {
//01.根据用户名称检索用户对象 Spring Security
public SysUser loadUserByUsername(String username);
} //1.2 创建IPermissionDAO
import cn.happy.entity.Permission;
import java.util.List;
public interface IPermissionDAO {
//01.查询所有权限集合 看用户能不能访问某个资源
public List<Permission> findAll();
//02.根据用户编号查询权限集合
public List<Permission> findByAdminUserId(int userId);
} 步骤六:
注意: service层不用写接口,因为SpringSecurity框架已经帮我们封装好了相关的方法
所以我们可以直接研发实现类即可:
import cn.happy.dao.IPermissionDAO;
import cn.happy.dao.IUserDAO;
import cn.happy.entity.Permission;
import cn.happy.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
//用户详情服务
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.util.ArrayList;
import java.util.List; public class UserServiceImpl implements UserDetailsService {
//在service层需要植入DAO的接口
@Autowired
private IUserDAO userDAO;
@Autowired
private IPermissionDAO permissionDAO;
@Override
public UserDetails loadUserByUsername(String username){
//1.调度的是我自己在DAO层定制的方法,只不过有一个巧合,就是我自己定制的方法和spring security中的方法名称一致。
SysUser sysUser = userDAO.loadUserByUsername(username);
//断定
if(sysUser!=null){ //有用户对象
//根据用户对象中的用户编号,获取该用户所拥有的所有权限集合
List<Permission> permissions=permissionDAO.findByAdminUserId(sysUser.getId());
//如果想让你的权限在UI层可以使用,必须进行包装,保证类型是GrantedAuthority
//1.先准备一个和框架对接的容器
List<GrantedAuthority> grantedAuthorities=new ArrayList<>();
//2.进行容器的替换
for(Permission permission:permissions){
//每个permission对象都是一个权限对象
if(permission != null && permission.getName()!= null){ //进行了双重校验,保证权限的准确性
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
//将单个grantedAuthority对象添加到集合中
grantedAuthorities.add(grantedAuthority);
}
}
return new User(sysUser.getUsername(),sysUser.getPassword(),grantedAuthorities);
}else{
throw new UsernameNotFoundException("admin:"+username+"do not exits");
} }
} 步骤七:
// 1.1.创建WebSecurityConfig 继承了 WebSecurityConfigurerAdapter
import cn.happy.service.impl.UserServiceImpl;
import cn.happy.util.MyPasswordEncoder;
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;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated() //任何请求,登录后可以访问
.and().formLogin() //基于表单的登录
.loginPage("/login") //登录页面
.failureUrl("/login-error") //错误页面
.permitAll() //登录和错误页面用户可以任意访问
.and()
.logout().permitAll();//注销行为可以任意访问
} @Bean
//UserDetailsService是一个接口
//意思是@Bean明确的指示了一种方法,什么方法呢----产生一个bean的方法,并且将bean实例交给spring容器管理
UserDetailsService customUserService(){
//向spring容器直接植入了一个Service
return new UserServiceImpl();
}
//定制了一个configuration
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {//认证管理构建器
auth.userDetailsService(customUserService()).passwordEncoder(new MyPasswordEncoder()); //user Details Service验证
}
} //1.2.上面的程序中需要传入一个MyPasswordEncoder()参数
那么我们就来创建一个自定义的密码编辑器 import org.springframework.security.crypto.password.PasswordEncoder; public class MyPasswordEncoder implements PasswordEncoder { @Override
public String encode(CharSequence arg0) {
return arg0.toString();
} @Override
public boolean matches(CharSequence arg0, String arg1) {
return arg1.equals(arg0.toString());
}
} 步骤八:
创建controller,实现一系列的调度和访问
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; @Controller
public class MainController {
@GetMapping("/index")
public String index(){
return "index";
} @GetMapping("/login")
public String login(){
return "login";
} @GetMapping("/login-error")
public String loginError(Model model){
model.addAttribute("loginError",true);
model.addAttribute("errorMsg","登录失败,用户名或密码错误");
return "login";
}
}
SpringSecurity结合数据库表实现权限认证的更多相关文章
- Codeigniter-实现权限认证
两种方法 钩子函数 集成核心Controller 方法一,钩子函数: 一直没找到CI的权限认证扩展,以前好像找到过一个老外的扩展,不过不怎么好用,现在记不清了,后来仿着jsp firter的方式用CI ...
- oracle数据库表实现主键自增功能
有关oracle中自增序列sequence+触发器trigger:实现数据表TABDATA_LIVE_CYCLE中的主键id的自增. CREATE SEQUENCE TABDATA_LIVE_CYCL ...
- Spring-Security (学习记录四)--配置权限过滤器,采用数据库方式获取权限
目录 1. 需要在spring-security.xml中配置验证过滤器,来取代spring-security.xml的默认过滤器 2. 配置securityMetadataSource,可以通过ur ...
- SpringSecurity——基于Spring、SpringMVC和MyBatis自定义SpringSecurity权限认证规则
本文转自:https://www.cnblogs.com/weilu2/p/springsecurity_custom_decision_metadata.html 本文在SpringMVC和MyBa ...
- SpringBoot之SpringSecurity权限注解在方法上进行权限认证多种方式
前言 Spring Security支持方法级别的权限控制.在此机制上,我们可以在任意层的任意方法上加入权限注解,加入注解的方法将自动被Spring Security保护起来,仅仅允许特定的用户访问, ...
- 权限认证 cookie VS token
权限认证 cookie VS token 我前公司的应用都是 token 授权的,现公司都是维护一个 session 确认登录状态的.那么我在这掰扯掰扯这两种权限认证的方方面面. 工作流程 先说 co ...
- 基于SpringSecurity和JWT的用户访问认证和授权
发布时间:2018-12-03 技术:springsecurity+jwt+java+jpa+mysql+mysql workBench 概述 基于SpringSecurity和JWT的用户访 ...
- spring-boot整合shiro作权限认证
spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro 废话不多说 引入pom文件 <!--shiro集成spring--& ...
- SpringSecurity 自定义用户 角色 资源权限控制
SpringSecurity 自定义用户 角色 资源权限控制 package com.joyen.learning.security; import java.sql.ResultSet; impor ...
随机推荐
- 洛谷P4288||bzoj3564 [SHOI2014]信号增幅仪
bzoj3564 洛谷P4288 可以旋转一下坐标轴使得x轴与长轴方向对齐,然后将所有的横坐标变为自身除以放大倍数,然后就做一个最小圆覆盖 #include<cstdio> #includ ...
- wireshark工具集
tshark 查看pcap文件第一个包的时间,当文件名不包含时间信息时非常有帮助 tshark -c 1 -T fields -e frame.time -r test.pcap dumpcap ed ...
- csu 1551: Longest Increasing Subsequence Again BIT + 思维
预处理last[i]表示以第i个开始,的合法后缀. pre[i]表示以第i个结尾,的合法前缀. 那么每一个数a[i],肯定是一个合法后缀last[i] + 一个合法前缀,那么合法前缀的数字要小于a[i ...
- hdu 5971 Wrestling Match 判断能否构成二分图
http://acm.hdu.edu.cn/showproblem.php?pid=5971 Wrestling Match Time Limit: 2000/1000 MS (Java/Others ...
- VMware下OSSIM 5.2.0的下载、安装和初步使用(图文详解)
不多说,直接上干货! 入门阶段不建议选用最新的版本. 采用OSSIM 4.11 到 OSSIM5.0.3 之间任何版本做实验,sensor的状态都会是“V”. 建议,入门,采用OSSIM5.0.0 ...
- 【javascript】2017-9-12 腾讯笔试小Q升序算法
刚做完笔试,腾讯笔试系统真的不友好,作为一个前端,我只会用js写编程题,然而,然而腾讯笔试系统连js输入函数都没给,还不准跳出页面,那个调试结果一直显示错误,我一直找不到错误在哪,心累. 只做了一道笔 ...
- 降低PNG图片存储大小方法、图片压缩方法
降低PNG图片存储大小方法,图片压缩方法,如何降低PNG图片存储大小?前提是分辨率和尺寸大小不变,图形的透明部分不变.请看如下办法,亲测可用. 1. 将PNG图片用PS打开. 2. 图像-模式-8位/ ...
- android 插件化框架speed-tools
项目介绍: speed-tools 是一款基于代理模式的动态部署apk热更新框架.插件化开发框架: speed-tools这个名字主要指的快速迭代开发工具集的意思. 功能与特性: 1.支持Androi ...
- 洛谷 P1309 瑞士轮
题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分 ...
- 如何诊断 11.2 集群节点驱逐问题 (文档 ID 1674872.1)
适用于: Oracle Database - Enterprise Edition - 版本 11.2.0.1 到 11.2.0.2 [发行版 11.2]本文档所含信息适用于所有平台 用途 这篇文档提 ...