1.JdbcRealm介绍
认证流程(JdbcRealm)
- subject调用login方法,将包含用户名密码的token传递给SecurityManager
- SecurityManager就会调用认证器(Authenticator)进行认证
- Authenticator就将token传递给绑定的Realm,在Realm中进行用户的认证检查;如果认证通过则正常执行,不通过则抛出认证异常
2.JdbcRealm规定的表结构
- 用户信息表:users
-
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("zhagnsan","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
-
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("zhagnsan",'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
create table roles_permissions(
id int primary key auto_increment,
role_name varchar(100) not null,
permission varchar(100) not null
);
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");
3.SpringBoot整合Shiro
创建spring boot应用添加依赖(同1)
配置shiro
package com.qfedu.shiro3.config;
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 {
//shiro方言
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
@Bean
public JdbcRealm getJdbcReam(DataSource dataSource){
JdbcRealm jdbcRealm = new JdbcRealm();
//JdbcRealm会自动从数据库查询用户及权限数据(数据库的表结构要符合JdbcRealm的规范)
jdbcRealm.setDataSource(dataSource);
//JdbcRealm默认开启认证功能,需要手动开启授权功能
jdbcRealm.setPermissionsLookupEnabled(true);
return jdbcRealm;
}
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(JdbcRealm jdbcRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(jdbcRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
//过滤器就是shiro进行权限校验的核心,进行认证和授权是需要SecurityManager的
filter.setSecurityManager(securityManager);
/*设置shiro的拦截规则
anon 匿名用户可访问
authc 认证用户可访问
user 使用RemeberMe的用户可访问
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;
}
}
4.认证页面同1
5.Shiro标签的使用
当用户认证进入到主页面后,需要显示用户信息和当前用户的权限信息,shiro就提供了一套标签用在页面来进行权限数据的呈现
shiro提供了可供jsp使用的标签以及Thymeleaf中标签
jsp页面引用
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
Thymeleaf模板中引用
pom文件中导入thymeleaf模板对shiro标签支持的依赖
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
在shiroconfig中配置shiro的方言支持
@Configuration
public class ShiroConfig {
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
Thymeleaf模板中引入shiro的命名空间
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
...
</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/>
<!--guest判断用户是否是游客身份,是则显示此标签内容-->
<shiro:guest>
游客:<a href="login.html">登录</a>
</shiro:guest>
<!--user判断用户是否是认证身份,是则显示-->
<shiro:user>
<!--principal获取当前登录用户名-->
用户【<shiro:principal/>】欢迎您
<!-- hasRole获取用户角色-->
当前用户为<shiro:hasRole name="admin">超级管理员</shiro:hasRole>
订单管理
<!-- hasPermission当前用户有权限则显示-->
<shiro:hasPermission name="sys:x:save"><a href="#">添加订单</a></shiro:hasPermission>
</shiro:user>
</body>
</html>