之前我们完成了Spring+Shiro的最基本配置搭建,现在我们再增加上DB,毕竟没有哪个系统会将用户、角色、权限等信息硬编码到代码里。DB选用myslq。

数据库准备

脚本如下。依然是两个用户:admin和guest。admin拥有角色admin以及权限permission1、permission2;guest拥有角色guest以及权限permission1、permission2。

create table test.shiro_user (
id int auto_increment primary key,
username varchar(50),
password varchar(50)
); create table test.shiro_role (
id int auto_increment primary key,
role varchar(50)
); create table test.shiro_permission (
id int auto_increment primary key,
permission varchar(50)
); create table test.shiro_user_r_role (
userid int,
roleid int
); create table test.shiro_user_r_permission (
userid int,
permissionid int
); insert into test.shiro_user(id, username, password) values (1, 'admin', 'admin');
insert into test.shiro_user(id, username, password) values (2, 'guest', 'guest'); insert into test.shiro_role(id, role) values (1, 'admin');
insert into test.shiro_role(id, role) values (2, 'guest'); insert into test.shiro_permission(id, permission) values (1, 'permission1');
insert into test.shiro_permission(id, permission) values (2, 'permission2');
insert into test.shiro_permission(id, permission) values (3, 'permission3');
insert into test.shiro_permission(id, permission) values (4, 'permission4'); insert into test.shiro_user_r_role(userid, roleid) values (1, 1);
insert into test.shiro_user_r_role(userid, roleid) values (2, 2); insert into test.shiro_user_r_permission(userid, permissionid) values (1, 1);
insert into test.shiro_user_r_permission(userid, permissionid) values (1, 2);
insert into test.shiro_user_r_permission(userid, permissionid) values (2, 3);
insert into test.shiro_user_r_permission(userid, permissionid) values (2, 4);

pom依赖

再之前的基础上又增加了spring-jdbc和mysql的数据库驱动,因为要连接数据库嘛

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

application.properties

增加连接数据库的相关配置

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.2.12:3306/test?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=onceas

Dao和Service

dao和service就没什么好说的了,Controller不用动

@Repository
public class LoginDao { private final JdbcTemplate jdbcTemplate; @Autowired
public LoginDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} public List<User> getUserByUsername(String username) {
String sql = "select id, username, password from shiro_user where username=?";
return jdbcTemplate.query(sql, new Object[]{username}, new BeanPropertyRowMapper<User>(User.class));
} public List<String> getRoleByUsername(String username) {
String sql = "select role from shiro_role A " +
"join shiro_user_r_role B on A.id = B.roleid " +
"join shiro_user C on B.userid = C.id " +
"where C.username=?";
return jdbcTemplate.queryForList(sql, new Object[]{username}, String.class);
} public List<String> getPermissionByUsername(String username) {
String sql = "select permission from shiro_permission A " +
"join shiro_user_r_permission B on A.id = B.permissionid " +
"join shiro_user C on B.userid = C.id " +
"where C.username=?";
return jdbcTemplate.queryForList(sql, new Object[]{username}, String.class);
}
}
@Service
public class LoginService { private final LoginDao loginDao; @Autowired
public LoginService(LoginDao loginDao) {
this.loginDao = loginDao;
} public List<User> getUserByUsername(String username) {
return loginDao.getUserByUsername(username);
} public List<String> getRoleByUsername(String username) {
return loginDao.getRoleByUsername(username);
} public List<String> getPermissionByUsername(String username) {
return loginDao.getPermissionByUsername(username);
}
}

修改Realm

调整Realm,用户验证和授权改为从数据库中获取数据

public class PropertiesRealm extends AuthorizingRealm {

    private final LoginService loginService;

    @Autowired
public PropertiesRealm(LoginService loginService) {
this.loginService = loginService;
} // 用户认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if (authenticationToken instanceof UsernamePasswordToken) {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
String password = new String(token.getPassword());
List<User> users = loginService.getUserByUsername(username);
if (users == null || users.size() != 1) {
throw new AuthenticationException("用户名或密码错误");
}
User user = users.get(0);
if (!user.getPassword().equals(password)) {
throw new AuthenticationException("用户名或密码错误");
}
return new SimpleAuthenticationInfo(username, password, getName());
} else if (authenticationToken instanceof RememberMeAuthenticationToken) {
RememberMeAuthenticationToken token = (RememberMeAuthenticationToken) authenticationToken;
// TODO: 2018/10/24
return null;
} else if (authenticationToken instanceof HostAuthenticationToken) {
HostAuthenticationToken token = (HostAuthenticationToken) authenticationToken;
// TODO: 2018/10/24
return null;
} else {
throw new AuthenticationException("未知的AuthenticationToken类型");
}
} // 用户授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.addRoles(loginService.getRoleByUsername(username));
simpleAuthorizationInfo.addStringPermissions(loginService.getPermissionByUsername(username));
return simpleAuthorizationInfo;
}
}

调整SpringApplication

因为修改后的realm需要LoginService的支持,所以相应的调整SpringApplication,其他地方不变。

@Bean
public PropertiesRealm propertiesRealm(LoginService loginService) {
return new PropertiesRealm(loginService);
}

SpringBoot+Shiro+DB (二)的更多相关文章

  1. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

  2. springboot shiro没有注解解决方案

    颓废的悠然   springboot shiro开启注释 shiroconfiguration中增加 1 2 3 4 5 6 7 @Bean     public AuthorizationAttri ...

  3. 前端基于vue,后台采用springboot+shiro的方式搭建的一个移动端商品展示平台

    基于vue实现的移动端商品展示页,可以web-view的方式嵌入到小程序中,布局简约.大气,减少初学者或开发者不必要的工作量.后台维护采用的springboot+shiro的方式,为广大爱好者提供展示 ...

  4. springboot-权限控制shiro(二)

    目录 1. 场景描述 2. 解决方案 1. 场景描述 (1)最近有点小忙,公司真实项目内容有点小多以及不想只介绍理论,就使用springboot单独部署了个shiro的demo项目,还是理论和实际项结 ...

  5. SpringBoot+Shiro (一)

    从网上搜索SpringBoot+Shiro相关文章,大部分都需要DB和Ecache的支持.这里提供一个最简单的Spring+Shiro的配置. 前言: 1. 由于SpringBoot官方已经不再建议使 ...

  6. SpringBoot&Shiro实现权限管理

    SpringBoot&Shiro实现权限管理 引言 相信大家前来看这篇文章的时候,是有SpringBoot和Shiro基础的,所以本文只介绍整合的步骤,如果哪里写的不好,恳请大家能指出错误,谢 ...

  7. springboot + shiro + cas4.2.7 实战

    1. 下载地址 https://github.com/apereo/cas/archive/v4.2.7.zip 2. 解压后, 用intellj idea 打开 3. 执行 gradle build ...

  8. springboot+shiro

    作者:纯洁的微笑 出处:http://www.ityouknow.com/ 这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公 ...

  9. SpringBoot进阶教程(二十九)整合Redis 发布订阅

    SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH 实现了 发布/订阅消息范例,发送者 (publishers) 不用编程就可以向特定的接受者发送消息 (subscribers). Ra ...

随机推荐

  1. BVS安全检测之检查Linux是否口令生存周期

    口令生存周期的配置文件为 /etc/login.defs vim 打开该文件,命令模式下输入 /PASS_MAX_DAYS 找到该配置信息的位置 我的Linux操作系统默认显示的是99999,说明我当 ...

  2. ROS常用库(四)API学习之常用common_msgs(下)

    一.前言 承接ROS常用库(三)API学习之常用common_msgs(上). 二.sensor_msgs 1.sensor_msgs / BatteryState.msg #电源状态 uint8 P ...

  3. 047、Java中使用if…else if…else判断

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  4. Good Bye 2019

    A.Card Game 题目大意:两个人都有共有n张卡牌,每张卡牌上都有一个数xi,没有两张牌上的数相同,且xi不小于1不大于n.每次两个人选出一张牌来,牌上数字大的人赢得此局,如果谁最后手上拥有所有 ...

  5. LocalDateTime整合到SpringBoot + MyBatis中

    啥也不说先贴两个代码: 一:MVC层配置 @Configuration public class JacksonConfig { /** 默认日期时间格式 */ public static final ...

  6. Python 操作 sqlite

    代码示例 #导入sqlite3库 import sqlite3 #连接数据库 conn = sqlite3.connect("customers.db") #创建表,主键id自增 ...

  7. jenkins打包iOS 报错:error: exportArchive: The data couldn’t be read because it isn’t in the correct format.

    在执行ios 打包的时候,我们通过执行下面的指令来打包ipa: mkdir arch archive_path=arch/${app_name}.xcarchive workspace_name=HP ...

  8. js实现二叉查找树

    二叉树的特点:   像一颗树一样,从顶端往下延伸,最顶端的为根节点,每个节点下面子节点的数不超过两个,没有任何子节点的节点被称为叶子节点, 除了根节点和叶子节点的被称为中间节点. 二叉查找树: 每个节 ...

  9. oracle 开发注意事项

    新建表或字段时,不能使用char,统一使用varcha,防止判断null时有遗漏 新建表,索引,序列,新增删除或修改字段的时候,要先判断操作的对象是否存在,否则SLQ会报错 插入或者修改特殊字符,解决 ...

  10. 137-PHP static修饰的类属性

    <?php class test{ //定义一个类 public static $num=0; //定义static修饰的类属性 public function __construct(){ / ...