springboot整合shiro应用
1、Shiro是Apache下的一个开源项目,我们称之为Apache Shiro。它是一个很易用与Java项目的的安全框架,提供了认证、授权、加密、会话管理,与spring Security 一样都是做一个权限的安全框架,但是与Spring Security 相比,在于 Shiro 使用了比较简单易懂易于使用的授权方式。shiro属于轻量级框架,相对于security简单的多,也没有security那么复杂。所以我这里也是简单介绍一下shiro的使用。
2、非常简单;其基本功能点如下图所示:

Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
记住一点,Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。
3、这里我就简单介绍一下springboot和shiro整合与基本使用。
1)目录结构

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.troy</groupId>
<artifactId>springshiro</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-Java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.4</version>
</dependency>
</dependencies> </project>

3)基本配置application.yml

server:
port: 8082
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring_shiro?useUnicode=true&characterEncoding=UTF-8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
jpa:
show-sql: true
hibernate:
ddl-auto: update
http:
encoding:
charset: utf-8
enabled: true

4)这里我们基本需要3个实体,用户,角色和权限
(1)角色:User.class

@Entity
public class User { @Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(unique = true)
private String name;
private Integer password;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "user")
private List<Role> roles; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public List<Role> getRoles() {
return roles;
} public void setRoles(List<Role> roles) {
this.roles = roles;
} public Integer getPassword() {
return password;
} public void setPassword(Integer password) {
this.password = password;
}
}

注:这里我只考虑一个用户对多个角色,不考虑多对多的关系
(2)角色:Role.class

@Entity
public class Role { @Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String roleName;
@ManyToOne(fetch = FetchType.EAGER)
private User user;
@OneToMany(cascade = CascadeType.ALL,mappedBy = "role")
private List<Permission> permissions; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getRoleName() {
return roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} public List<Permission> getPermissions() {
return permissions;
} public void setPermissions(List<Permission> permissions) {
this.permissions = permissions;
}
}

(3)权限:Permission.class

@Entity
public class Permission { @Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String permission;
@ManyToOne(fetch = FetchType.EAGER)
private Role role; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getPermission() {
return permission;
} public void setPermission(String permission) {
this.permission = permission;
} public Role getRole() {
return role;
} public void setRole(Role role) {
this.role = role;
}
}

5)然后就是配置对应的验证,以及过滤条件
(1)验证,以及权限的添加MyShiroRealm.class

//实现AuthorizingRealm接口用户用户认证
public class MyShiroRealm extends AuthorizingRealm{ //用于用户查询
@Autowired
private ILoginService loginService; //角色权限和对应权限添加
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取登录用户名
String name= (String) principalCollection.getPrimaryPrincipal();
//查询用户名称
User user = loginService.findByName(name);
//添加角色和权限
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
for (Role role:user.getRoles()) {
//添加角色
simpleAuthorizationInfo.addRole(role.getRoleName());
for (Permission permission:role.getPermissions()) {
//添加权限
simpleAuthorizationInfo.addStringPermission(permission.getPermission());
}
}
return simpleAuthorizationInfo;
} //用户认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//加这一步的目的是在Post请求的时候会先进认证,然后在到请求
if (authenticationToken.getPrincipal() == null) {
return null;
}
//获取用户信息
String name = authenticationToken.getPrincipal().toString();
User user = loginService.findByName(name);
if (user == null) {
//这里返回后会报出对应异常
return null;
} else {
//这里验证authenticationToken和simpleAuthenticationInfo的信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
return simpleAuthenticationInfo;
}
}
}

(2)过滤配置:ShiroConfiguration.class

@Configuration
public class ShiroConfiguration { //将自己的验证方式加入容器
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
} //权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
} //Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> map = new HashMap<String, String>();
//登出
map.put("/logout","logout");
//对所有用户认证
map.put("/**","authc");
//登录
shiroFilterFactoryBean.setLoginUrl("/login");
//首页
shiroFilterFactoryBean.setSuccessUrl("/index");
//错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/error");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
} //加入注解的使用,不加入这个注解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}

6)接下来就是数据访问层、业务层、以及控制层
(1)数据层:BaseRepository.class,UserRepository.class,RoleRepository.class
@NoRepositoryBean
public interface BaseRepository<T,I extends Serializable> extends PagingAndSortingRepository<T,I>,JpaSpecificationExecutor<T>{ }
public interface UserRepository extends BaseRepository<User,Long>{
User findByName(String name);
}
public interface RoleRepository extends BaseRepository<Role,Long> {
}
(2)业务层:LoginServiceImpl.class

@Service
@Transactional
public class LoginServiceImpl implements ILoginService { @Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository; //添加用户
@Override
public User addUser(Map<String, Object> map) {
User user = new User();
user.setName(map.get("username").toString());
user.setPassword(Integer.valueOf(map.get("password").toString()));
userRepository.save(user);
return user;
} //添加角色
@Override
public Role addRole(Map<String, Object> map) {
User user = userRepository.findOne(Long.valueOf(map.get("userId").toString()));
Role role = new Role();
role.setRoleName(map.get("roleName").toString());
role.setUser(user);
Permission permission1 = new Permission();
permission1.setPermission("create");
permission1.setRole(role);
Permission permission2 = new Permission();
permission2.setPermission("update");
permission2.setRole(role);
List<Permission> permissions = new ArrayList<Permission>();
permissions.add(permission1);
permissions.add(permission2);
role.setPermissions(permissions);
roleRepository.save(role);
return role;
} //查询用户通过用户名
@Override
public User findByName(String name) {
return userRepository.findByName(name);
}
}

(3)控制层:LoginResource.class

@RestController
public class LoginResource { @Autowired
private ILoginService loginService; //退出的时候是get请求,主要是用于退出
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){
return "login";
} //post登录
@RequestMapping(value = "/login",method = RequestMethod.POST)
public String login(@RequestBody Map map){
//添加用户认证信息
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
map.get("username").toString(),
map.get("password").toString());
//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);
return "login";
} @RequestMapping(value = "/index")
public String index(){
return "index";
} //登出
@RequestMapping(value = "/logout")
public String logout(){
return "logout";
} //错误页面展示
@RequestMapping(value = "/error",method = RequestMethod.POST)
public String error(){
return "error ok!";
} //数据初始化
@RequestMapping(value = "/addUser")
public String addUser(@RequestBody Map<String,Object> map){
User user = loginService.addUser(map);
return "addUser is ok! \n" + user;
} //角色初始化
@RequestMapping(value = "/addRole")
public String addRole(@RequestBody Map<String,Object> map){
Role role = loginService.addRole(map);
return "addRole is ok! \n" + role;
} //注解的使用
@RequiresRoles("admin")
@RequiresPermissions("create")
@RequestMapping(value = "/create")
public String create(){
return "Create success!";
}
}

注:这里对于注解的使用,在最后一个很重要!
7)shiro的使用基本上就是这样子了,主要是权限的控制,其他的主要是做跳转和切换使用
8)最后配上数据库信息:结合控制层观看
user:

role:

permission:

springboot整合shiro应用的更多相关文章
- 补习系列(6)- springboot 整合 shiro 一指禅
目标 了解ApacheShiro是什么,能做什么: 通过QuickStart 代码领会 Shiro的关键概念: 能基于SpringBoot 整合Shiro 实现URL安全访问: 掌握基于注解的方法,以 ...
- SpringBoot系列十二:SpringBoot整合 Shiro
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Shiro 2.具体内容 Shiro 是现在最为流行的权限认证开发框架,与它起名的只有最初 ...
- SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建
SpringBoot整合Shiro实现基于角色的权限访问控制(RBAC)系统简单设计从零搭建 技术栈 : SpringBoot + shiro + jpa + freemark ,因为篇幅原因,这里只 ...
- 转:30分钟了解Springboot整合Shiro
引自:30分钟了解Springboot整合Shiro 前言:06年7月的某日,不才创作了一篇题为<30分钟学会如何使用Shiro>的文章.不在意之间居然斩获了22万的阅读量,许多人因此加了 ...
- springboot整合Shiro功能案例
Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...
- SpringBoot整合Shiro实现权限控制,验证码
本文介绍 SpringBoot 整合 shiro,相对于 Spring Security 而言,shiro 更加简单,没有那么复杂. 目前我的需求是一个博客系统,有用户和管理员两种角色.一个用户可能有 ...
- SpringBoot 整合Shiro 一指禅
目标 了解ApacheShiro是什么,能做什么: 通过QuickStart 代码领会 Shiro的关键概念: 能基于SpringBoot 整合Shiro 实现URL安全访问: 掌握基于注解的方法,以 ...
- SpringBoot整合Shiro+MD5+Salt+Redis实现认证和动态权限管理(上)----筑基中期
写在前面 通过前几篇文章的学习,我们从大体上了解了shiro关于认证和授权方面的应用.在接下来的文章当中,我将通过一个demo,带领大家搭建一个SpringBoot整合Shiro的一个项目开发脚手架, ...
- SpringBoot整合Shiro+MD5+Salt+Redis实现认证和动态权限管理|前后端分离(下)----筑基后期
写在前面 在上一篇文章<SpringBoot整合Shiro+MD5+Salt+Redis实现认证和动态权限管理(上)----筑基中期>当中,我们初步实现了SpringBoot整合Shiro ...
- SpringBoot整合Shiro权限框架实战
什么是ACL和RBAC ACL Access Control list:访问控制列表 优点:简单易用,开发便捷 缺点:用户和权限直接挂钩,导致在授予时的复杂性,比较分散,不便于管理 例子:常见的文件系 ...
随机推荐
- css公共库——清除浮动
清除浮动是css的基础,但有时候会忘了一些最简单的东西 浮动因为在文档流之外,所以会造成父元素的坍塌.父元素之后的元素排版就会乱. 常用的方法是在浮动父元素中添加cf类,然后定义cf样式,并将其放在公 ...
- Win64下编译集成GEOS和Proj4的GDAL
目录 1.编译GEOS 2.编译Proj4 3.GDAL集成Proj4和GEOS 1) 修改安装的目录 2) 配置Proj4 3) 配置GEOS 4) 自定义动态库名称(可跳过) 5) 编译 1.编译 ...
- Hexo + GitHub 搭建个人博客
对于程序员来说,搭建和维护一个个人博客十分必要,写博客既是对所学知识的整理和总结,同时也能向他人展现自己的学习成果.这篇教程就是基于 Hexo 和 GitHub 来搭建属于自己的个人博客,简单快捷, ...
- Mysql8 安装过程及安装过程系列问题记录
前言: 今天,想装个高版本一点的mysql试试,于是下载了一个mysql8的zip版本. 地址:https://dev.mysql.com/downloads/file/?id=484900 没想到安 ...
- Quartz简单实现定时任务管理(SSM+Quartz)
首先你得有一个用Maven搭好的SSM框架,数据库用的Mysql,这里只有关于Quartz的部分.其实有大神总结的很好了,但做完后总有些地方不一样,所以写这篇作为笔记.这里先把大神的写的分享给大家:h ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十一║Vue实战:开发环境搭建【详细版】
缘起 哈喽大家好,兜兜转转终于来到了Vue实战环节,前边的 6 篇关于Vue基础文章我刚刚简单看了看,感觉写的还是不行呀,不是很系统,所以大家可能看上去比较累,还是得抽时间去润润色,修改修改语句和样式 ...
- Redis集群伸缩
集群扩容 前提准备,目前集群中一共有6台机器,端口号分别是6381.6382.6383.6384.6385.6386 1) 准备新节点 准备两个新节点,端口号为6387和6388,配置和以前集群配置一 ...
- 机器学习之决策树二-C4.5原理与代码实现
决策树之系列二—C4.5原理与代码实现 本文系作者原创,转载请注明出处:https://www.cnblogs.com/further-further-further/p/9435712.html I ...
- [JavaScript] 函数节流(throttle)和函数防抖(debounce)
js 的函数节流(throttle)和函数防抖(debounce)概述 函数防抖(debounce) 一个事件频繁触发,但是我们不想让他触发的这么频繁,于是我们就设置一个定时器让这个事件在 xxx 秒 ...
- pytorch深度学习60分钟闪电战
https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html 官方推荐的一篇教程 Tensors #Construct a ...