Shiro
-
- 一,什么是Shiro
- 二,Shiro核心组件
- 三,Shiro的运行机制图
- 四,Shiro的认证和授权规则
- 五,SpringBoot整合Shiro
-
- 使用Shiro做权限管理
-
-
- 1,数据库
- 2,创建springboot项目,导入依赖
- 3,编写yml文件
- 4,编写实体类
- 5,编写dao
- 6,编写service及实现类
- 7,编写realm类
- 8,编写config类
- 9,编写controller类
- 10,页面
- 测试结果
- 代码下载地址
-
一,什么是Shiro 官网
Shiro是一款主流的java安全框架,不依赖任何容器可以运行在javase和javaee项目中,它的主要作用
是访问系统的用户进行身份认证,授权,会话管理,加密等操作
Shiro就是用来解决安全管理的系统化框架
二,Shiro核心组件
- UsernamePasswordToken:Shiro用来封装用户登录信息,使用用户的登录信息来创建令牌Token
- SecurityManager:Shiro的核心部分,负责安全认证和授权
- Suject:Shiro的一个抽象概念,包含了用户信息
- Realm:开发者自定义的模板,根据项目的需求验证和授权的逻辑全部写在Realm中
- AuthenticationInfo:用户的角色信息集合,认证时使用
- AuthorzationInfo:角色的权限信息集合,授权时使用
- DefaultWebSecurityManager:安全管理器,开发者自定义的Realm需要注入到DefaultWebSecurityManager进行管理才能生效
- ShiroFIlterFactoryBean:过滤器工作,Shiro的基本运行机制是开发者定制规则,Shiro去执行,具体的执行操作就是由ShiroFIlterFactoryBean窗机 的一个个Filter对象来完成的
文章图片
四,Shiro的认证和授权规则
- 认证过滤器
- anon:无需认证
- authc:必须认证
- authcBasic:需要通过HttpBasic认证
- user:不一定通过认证,只需要曾经被Shiro记录即可
- 授权过滤器
- Perms:必须拥有某个权限才能访问
- role:必须拥有某个角色才能访问
- port:请求的端口必须是指定值才可以
- rest:请求必须基于RestFul风格
- ssl:必须是安全的url请求,协议HTTPS
1,数据库
-- MySQL dump 10.13Distrib 8.0.19, for Win64 (x86_64)
--
-- Host: 127.0.0.1Database: test
-- ------------------------------------------------------
-- Server version 8.0.19/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `account`
--DROP TABLE IF EXISTS `account`;
/*!40101 SET @saved_cs_client= @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `account` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`perms` varchar(20) DEFAULT NULL,
`role` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `account`
--LOCK TABLES `account` WRITE;
/*!40000 ALTER TABLE `account` DISABLE KEYS */;
INSERT INTO `account` VALUES (1,'zs','123123','',''),(2,'ls','123123','manage','administrator'),(3,'ww','123123','','');
/*!40000 ALTER TABLE `account` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-06-04 14:10:15
2,创建springboot项目,导入依赖
4.0.0 org.springframework.boot
spring-boot-starter-parent
2.1.11.RELEASE
com.bd13
springboot-shiro
0.0.1-SNAPSHOT
springboot-shiro
Demo project for Spring Boot 1.8
org.apache.shiro
shiro-spring
1.5.3
mysql
mysql-connector-java
com.baomidou
mybatis-plus-boot-starter
3.3.1.tmp
com.github.theborakompanioni
thymeleaf-extras-shiro
2.0.0
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
>test
org.springframework.boot
spring-boot-maven-plugin
3,编写yml文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 09301225
url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8
thymeleaf:
prefix: classpath:/templates/
suffix: .html
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4,编写实体类
package com.bd13.springbootshiro.entity;
public class Account {private Integer id;
private String username;
private String password;
private String perms;
private String role;
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;
}public String getPerms() {return perms;
}public void setPerms(String perms) {this.perms = perms;
}public String getRole() {return role;
}public void setRole(String role) {this.role = role;
}
}
5,编写dao
package com.bd13.springbootshiro.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bd13.springbootshiro.entity.Account;
public interface AccountMapper extends BaseMapper {}
6,编写service及实现类
package com.bd13.springbootshiro.service;
import com.bd13.springbootshiro.entity.Account;
public interface AccountService {public Account findByUsername(String username);
}
package com.bd13.springbootshiro.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bd13.springbootshiro.entity.Account;
import com.bd13.springbootshiro.mapper.AccountMapper;
import com.bd13.springbootshiro.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountServiceImpl implements AccountService {@Autowired
private AccountMapper accountMapper;
@Override
public Account findByUsername(String username) {QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("username",username);
return accountMapper.selectOne(wrapper);
}
}
7,编写realm类
package com.bd13.springbootshiro.realm;
import com.bd13.springbootshiro.entity.Account;
import com.bd13.springbootshiro.service.AccountService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
public class AccountRealm extends AuthorizingRealm {@Autowired
private AccountService accountService;
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//获取当前登录的用户信息
Subject subject= SecurityUtils.getSubject();
Account account = (Account) subject.getPrincipal();
//设置角色
Set> roles=new HashSet<>();
roles.add(account.getRole());
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(roles);
//设置权限
info.addStringPermission(account.getPerms());
return info;
}@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
Account account = accountService.findByUsername(token.getUsername());
if (account != null){return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
}
return null;
}
}
8,编写config类
package com.bd13.springbootshiro.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.bd13.springbootshiro.realm.AccountRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Hashtable;
import java.util.Map;
@Configuration
public class ShiroConfig {@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
//权限设置
Map,String> map=new Hashtable<>();
map.put("/main","authc");
//map.put("/manage","perms[manage]");
//map.put("/administrator","roles[administrator]");
factoryBean.setFilterChainDefinitionMap(map);
//设置登录页面
factoryBean.setLoginUrl("/login");
//设置未授权页面
factoryBean.setUnauthorizedUrl("/unaurh");
return factoryBean;
}@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("accountRealm") AccountRealm accountRealm){DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(accountRealm);
return manager;
}@Bean
public AccountRealm accountRealm(){return new AccountRealm();
}@Bean
public ShiroDialect shiroDialect(){return new ShiroDialect();
}
}
9,编写controller类
package com.bd13.springbootshiro.controller;
import com.bd13.springbootshiro.entity.Account;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class AccountController {@GetMapping("/{url}")
public String redirect(@PathVariable("url")String url){return url;
}
@PostMapping("/login")
public String login(String username, String password, Model model){Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{subject.login(token);
Account account= (Account) subject.getPrincipal();
subject.getSession().setAttribute("account",account);
return "index";
}catch (UnknownAccountException e){model.addAttribute("msg","用户名错误!");
return "login";
}catch (IncorrectCredentialsException e){model.addAttribute("msg","密码错误!");
return "login";
}
}@GetMapping("/unauth")
@ResponseBody
public String unauth(){return "未授权,无法访问!";
}@GetMapping("/logout")
public String logout(){Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
}
}
10,页面 login.html
Title - 锐客网
index.html
Title - 锐客网
index
th:text="${session.account.username}+'欢迎回来!'">退出
main
main.html
Title - 锐客网
main
manage.html
Title - 锐客网
manage
administrator.html
Title - 锐客网
administator
测试结果 普通用户登录
文章图片
管理员
文章图片
超级管理员
文章图片
代码下载地址 【浅谈Shiro安全框架】代码下载地址