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 ...
随机推荐
- HDU6298(2018多校第一场)
Bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6298 打表找规律: #include<bits/stdc++.h> usin ...
- 关于childNodes和children
1.childNodes. 会把注释.空文本.非空文本.标签都当做节点. 2.children: 在IE8以后的版本只会找到标签元素.不包括文本.空文本.注释.在IE8以前的版本会找到标签元素和注释, ...
- attribute与property区别总结
在前阵子看JQuery源码中,attr()的简单理解是调用了element.getAttribute()和element.setAttribute()方法,removeAttr()简单而言是调用ele ...
- Android -Cannot run program "XXX/sdk/tools/emulator": error=2, No such file or directory
I have installed android SDK and eclipse successfully on ubuntu 14.04. However,now it's not running. ...
- js AES对称加密 16进制和base64格式
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 单线程异步回调机制的缺陷与node的解决方案
一.node单线程异步的缺陷: 单线程异步的优点自然不必多说,node之所以能够如此快的兴起,其单线程异步回调机制相比于传统同步执行编程语言的优势便是原因之一.然而,开发一个node程序,其缺陷也是不 ...
- 【详解】JS中的作用域、闭包和回收机制
在讲解主要内容之前,我们先来看看JS的解析顺序,我们惯性地觉得JS是从上往下执行的,所以我们要用一个变量来首先声明它,来看下面这段代码: alert(a); var a = 1; 大家觉得这段代码有什 ...
- Android线程池(转)
.前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337 使用线程池可以给我们带来很多好处,首先通过线程池中线程的重用, ...
- selenium的定位
id定位 find_element_by_id()方法通过id来定位元素 例如: find_element_by_id("kw") find_element_by_id(&quo ...
- LibreOJ #103. 子串查找
题目描述 这是一道模板题. 给定一个字符串 A AA 和一个字符串 B BB,求 B BB 在 A AA 中的出现次数. A AA 中不同位置出现的 B BB 可重叠. 输入格式 输入共两行,分别是字 ...