之前我们完成了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. Adapter之GridAdapter

    前言: 在我们写界面的时候想让我们展示的页面是网格的,这是我们可以使用GridAdapter,这个和listView的使用有相似之处,如果学过ListView的话还是很简单的 正文: 下面我们来看看G ...

  2. IDEA自用插件,驼峰插件,MyBatis插件,Lombok插件

    IDEA自用插件 驼峰插件:CamelCase,Shift + Alt + u快速切换驼峰 MyBatisX插件:快速在mapper之间跳转 Lombok插件:注解实现get.set方法 MyBati ...

  3. 关于Orcale 11g 安装过程

    1.前往Oracle官网下载相应安装包 https://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.h ...

  4. java 接口 2.19

    接口中所有的方法都是抽象的和public的,所有的属性都是public,static,final的.

  5. XE10开发的APP对于苹果IPV6上架要求的处理

    1.服务器必须使用域名.不能使用IP地址2.Indy的话,域名加[]3.DataSnap的话,Params.Values['CommunicationIPVersion'] :='IP_IPv6';4 ...

  6. P1055 集体照

    P1055 集体照 转跳点:

  7. Python基础笔记:高级特性:切片、迭代、列表生成式、生成器、迭代器

    题记: 在python中,代码不是越多越好,而是越少越好.代码不是越复杂越好,而是越简单越好. 1行代码能实现的功能,绝不写5行代码. 请始终牢记:代码越少,开发效率越高. 切片 >>&g ...

  8. 解决:Server IPC version 9 cannot communicate with client version 4

    使用idea的maven项目运行mapreduce程序Server IPC version 9 cannot communicate with client version 4 原因: Java初始化 ...

  9. Vulkan SDK 之Render Pass

    Create a Render Pass A render pass describes the scope of a rendering operation by specifying the co ...

  10. 091-PHP数组过滤函数array_filter,过滤非整数

    <?php function not_int($x){ //定义过滤非整数的函数 if(is_int($x)) return TRUE; } $arr=array(1,2,'a',3,4,'c' ...