什么是 Shiro
官網(wǎng):http://shiro.apache.org/
是一款主流的 Java 安全框架,不依賴任何容器,可以運(yùn)行在 Java SE 和 Java EE 項(xiàng)目中,它的主要作用是對(duì)訪問系統(tǒng)的用戶進(jìn)行身份認(rèn)證、授權(quán)、會(huì)話管理、加密等操作。
Shiro 就是用來解決安全管理的系統(tǒng)化框架。
Shiro 核心組件
用戶、角色、權(quán)限
會(huì)給角色賦予權(quán)限,給用戶賦予角色
1、UsernamePasswordToken,Shiro 用來封裝用戶登錄信息,使用用戶的登錄信息來創(chuàng)建令牌 Token。
2、SecurityManager,Shiro 的核心部分,負(fù)責(zé)安全認(rèn)證和授權(quán)。
3、Subject,Shiro 的一個(gè)抽象概念,包含了用戶信息。
4、Realm,開發(fā)者自定義的模塊,根據(jù)項(xiàng)目的需求,驗(yàn)證和授權(quán)的邏輯全部寫在 Realm 中。
5、AuthenticationInfo,用戶的角色信息集合,認(rèn)證時(shí)使用。
6、AuthorzationInfo,角色的權(quán)限信息集合,授權(quán)時(shí)使用。
7、DefaultWebSecurityManager,安全管理器,開發(fā)者自定義的 Realm 需要注入到 DefaultWebSecurityManager 進(jìn)行管理才能生效。
8、ShiroFilterFactoryBean,過濾器工廠,Shiro 的基本運(yùn)行機(jī)制是開發(fā)者定制規(guī)則,Shiro 去執(zhí)行,具體的執(zhí)行操作就是由 ShiroFilterFactoryBean 創(chuàng)建的一個(gè)個(gè) Filter 對(duì)象來完成。
Shiro 的運(yùn)行機(jī)制如下圖所示。

Spring Boot 整合 Shiro
1、創(chuàng)建 Spring Boot 應(yīng)用,集成 Shiro 及相關(guān)組件,pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2、自定義 Shiro 過濾器
public class AccoutRealm extends AuthorizingRealm {
@Autowired
private AccountService accountService;
/**
* 授權(quán)
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 認(rèn)證
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@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;
}
}
3、配置類
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
return factoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("accoutRealm") AccoutRealm accoutRealm){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(accoutRealm);
return manager;
}
@Bean
public AccoutRealm accoutRealm(){
return new AccoutRealm();
}
}
編寫認(rèn)證和授權(quán)規(guī)則:
認(rèn)證過濾器
anon:無需認(rèn)證。
authc:必須認(rèn)證。
authcBasic:需要通過 HTTPBasic 認(rèn)證。
user:不一定通過認(rèn)證,只要曾經(jīng)被 Shiro 記錄即可,比如:記住我。
授權(quán)過濾器
perms:必須擁有某個(gè)權(quán)限才能訪問。
role:必須擁有某個(gè)角色才能訪問。
port:請(qǐng)求的端口必須是指定值才可以。
rest:請(qǐng)求必須基于 RESTful,POST、PUT、GET、DELETE。
ssl:必須是安全的 URL 請(qǐng)求,協(xié)議 HTTPS。
創(chuàng)建 3 個(gè)頁面,main.html、manage.html、administrator.html
訪問權(quán)限如下:
1、必須登錄才能訪問 main.html
2、當(dāng)前用戶必須擁有 manage 授權(quán)才能訪問 manage.html
3、當(dāng)前用戶必須擁有 administrator 角色才能訪問 administrator.html
Shiro 整合 Thymeleaf
1、pom.xml 引入依賴
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2、配置類添加 ShiroDialect
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
3、index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="shortcut icon" href="#"/>
</head>
<body>
<h1>index</h1>
<div th:if="${session.account != null}">
<span th:text="${session.account.username}+'歡迎回來!'"></span><a href="/logout">退出</a>
</div>
<a href="/main">main</a> <br/>
<div shiro:hasPermission="manage">
<a href="manage">manage</a> <br/>
</div>
<div shiro:hasRole="administrator">
<a href="/administrator">administrator</a>
</div>
</body>
</html>