一、SpringBoot应用整合Shiro
1.1创建SpringBoot应用
1.2整合Druid和Mybatis
导入依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>
配置
spring: datasource: druid: url: jdbc:mysql://localhost:3306/fmmall driver-class-name: com.mysql.jdbc.Driver username: root password: root initial-size: 1 min-idle: 1 max-active: 20 web: resources: static-locations: classpath:/templates/ mybatis: type-aliases-package: com.qfedu.shiro2.beans mapper-locations: classpath:mappers/*Mapper.xml
1.3整合Shiro
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency>
ShiroFilter
- 拦截用户请求
- 根据配置的拦截规则进行控制
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public IniRealm getIniRealm(){
IniRealm iniRealm=new IniRealm("classpath:shiro.ini");
return iniRealm;
}
//SecurityManager要完成验证,需要realm
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManage(IniRealm iniRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(iniRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
filter.setSecurityManager(securityManager);
//设置拦截规则
// anon匿名用户可访问
//authc 认证用户可以访问
//user 认证用户可以访问
//perms 对应权限可以访问
//role 对应的角色可以访问
Map<String,String> filterMap=new HashMap<>();
filterMap.put("/","anon");
filterMap.put("/login.html","anon");
filterMap.put("/regist.html","anon");
filterMap.put("/user/login","anon");
filterMap.put("/user/regist","anon");
filterMap.put("/static/**","anon");
filterMap.put("/**","authc");
filter.setFilterChainDefinitionMap(filterMap);
filter.setLoginUrl("/login.html");
filter.setUnauthorizedUrl("/login.html");
return filter;
}
}
resources/shiro.ini
[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=222222,admin
[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list
- 导入Shiro依赖
- 配置Shiro过滤器,拦截需要进行认证和授权的用户
- Spring容器配置SecurityManager
- 配置Realm!!!SecurityManager需要Realm
- Realm???可以Shiro提供,也可以自己定义
认证测试
UserServiceImpl.java
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl {
public void cheakLogin(String userName,String userPwd) throws Exception{
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(userName,userPwd);
subject.login(token);
}
}
UserController.java
import com.qfedu.shiro2.service.UserServiceImpl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserServiceImpl userService;
@RequestMapping("/login")
public String login(String userName,String userPwd){
try {
userService.cheakLogin(userName,userPwd);
System.out.println("成功!");
return "index";
}catch (Exception e){
System.out.println("登录失败!");
}
return "login";
}
}
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
login
<hr/>
<form action="/user/login">
<p>账号:<input type="text" name="userName"/> </p>
<p>密码:<input type="text" name="userPwd"/> </p>
<p><input type="submit" value="登录"/> </p>
</form>
</body>
</html>
二、SpringBoot应用整合Shiro——案例(JdbcRealm)
2.1如果使用JdbcRealm,则必须提供JdbcRealm所需的表结构(权限设计)
2.2JdbcRealm规定的表结构
用户信息表 users
角色信息表 user_roles
权限信息表:roles_permissions
- 用户信息表: users
```sql
create table users(
id int primary key auto_increment,
username varchar(60) not null unique,
password varchar(20) not null,
password_salt varchar(20)
);
insert into users(username,password) values('zhangsan','123456');
insert into users(username,password) values('lisi','123456');
insert into users(username,password) values('wangwu','123456');
insert into users(username,password) values('zhaoliu','123456');
insert into users(username,password) values('chenqi','123456');
```
- 角色信息表: user_roles
```sql
create table user_roles(
id int primary key auto_increment,
username varchar(60) not null,
role_name varchar(100) not null
);
-- admin系统管理员
-- cmanager 库管人员
-- xmanager 销售人员
-- kmanager 客服人员
-- zmanager 行政人员
insert into user_roles(username,role_name) values('zhangsan','admin');
insert into user_roles(username,role_name) values('lisi','cmanager');
insert into user_roles(username,role_name) values('wangwu','xmanager');
insert into user_roles(username,role_name) values('zhaoliu','kmanager');
insert into user_roles(username,role_name) values('chenqi','zmanager');
```
- 权限信息表:roles_permissions
```sql
create table roles_permissions(
id int primary key auto_increment,
role_name varchar(100) not null,
permission varchar(100) not null
);
-- 权限 sys:c:save sys:c:delete...
-- 管理员具备所有权限
insert into roles_permissions(role_name,permission) values("admin","*");
-- 库管人员
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:save");
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:delete");
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:update");
insert into roles_permissions(role_name,permission) values("cmanager","sys:c:find");
-- 销售人员
insert into roles_permissions(role_name,permission) values("xmanager","sys:c:find");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:save");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:delete");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:update");
insert into roles_permissions(role_name,permission) values("xmanager","sys:x:find");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:save");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:delete");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:update");
insert into roles_permissions(role_name,permission) values("xmanager","sys:k:find");
-- 客服人员
insert into roles_permissions(role_name,permission) values("kmanager","sys:k:find");
insert into roles_permissions(role_name,permission) values("kmanager","sys:k:update");
-- 新增人员
insert into roles_permissions(role_name,permission) values("zmanager","sys:*:find");
2.3SpringBoot整合Shiro
- 创建SpringBoot应用
- 整合Druid和MyBatis
- 整合shiro
- 添加依赖
```xml
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
- 配置Shiro
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
@Bean
public JdbcRealm getIniRealm(DataSource dataSource){
JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
//默认开启认证功能,需要手动开启授权功能
jdbcRealm.setPermissionsLookupEnabled(true);
return jdbcRealm;
}
//SecurityManager要完成验证,需要realm
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManage(JdbcRealm jdbcRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(jdbcRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
filter.setSecurityManager(securityManager);
//设置拦截规则
// anon匿名用户可访问
//authc 认证用户可以访问
//user 认证用户可以访问
//perms 对应权限可以访问
//role 对应的角色可以访问
Map<String,String> filterMap=new HashMap<>();
filterMap.put("/","anon");
filterMap.put("/login.html","anon");
filterMap.put("/index.html","anon");
filterMap.put("/user/login","anon");
filterMap.put("/user/regist","anon");
filterMap.put("/static/**","anon");
filterMap.put("/**","authc");
filter.setFilterChainDefinitionMap(filterMap);
filter.setLoginUrl("/login.html");
filter.setUnauthorizedUrl("/login.html");
return filter;
}
}
三、Shiro的标签使用
Shiro提供了可供JSP使用的标签以及Thymeleaf
- JSP页面中引用:
```jsp
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
```
Thymeleaf模板中引用
1.导入依赖
<dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
2.配置ShiroConfig
```java
@Configuration
public class ShiroConfig {
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
//...
}
3.Thymeleaf模版中引入shiro的命名空间
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
...
</html>
常用标签
- guest,判断用户是否是游客身份,如果是游客身份则显示此标签内容
<shiro:guest>
欢迎游客访问,<a href="login.html">登录</a>
</shiro:guest>
- user,判断用户是否是认证身份,如果是认证身份则显示此标签内容
- principal,获取当前登录用户名
<shiro:user>
用户[<shiro:principal/>]欢迎您!
</shiro:user>
- notAuthenticated/authenticated
- hasRole
- hasPermission
index.html案例
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
index
<hr/>
<shiro:guest>
欢迎游客访问,<a href="login.html">登录</a>
</shiro:guest>
<shiro:user>
用户[<shiro:principal/>]欢迎您!
当前用户角色为<Shiro:hasRole name="admin">超级管理员</Shiro:hasRole>
<shiro:hasRole name="cmanager">仓管人员</shiro:hasRole>
<shiro:hasRole name="xmanager">销售人员</shiro:hasRole>
<shiro:hasRole name="kmanager">客服人员</shiro:hasRole>
<shiro:hasRole name="zmanager">行政人员</shiro:hasRole>
</shiro:user>
<hr/>
仓库管理
<ul>
<shiro:hasPermission name="sys:c:save"><li><a href="#">入库</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:c:delete"><li><a href="#">出库</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:c:update"><li><a href="#">修改</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:c:find"><li><a href="#">查询</a></li></shiro:hasPermission>
</ul>
订单管理
<ul>
<shiro:hasPermission name="sys:x:save"><li><a href="#">添加订单</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:x:delete"><li><a href="#">删除订单</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:x:update"><li><a href="#">修改订单</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:x:find"><li><a href="#">查询订单</a></li></shiro:hasPermission>
</ul>
客户管理
<ul>
<shiro:hasPermission name="sys:k:save"><li><a href="#">添加客户</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:k:delete"><li><a href="#">删除客户</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:k:update"><li><a href="#">修改客户</a></li></shiro:hasPermission>
<shiro:hasPermission name="sys:k:find"><li><a href="#">查询客户</a></li></shiro:hasPermission>
</ul>
</body>
</html>