springboot+shiro整合(mybatis就不说了)
springboot使用jsp有个设置以下,不然会提示找不到jsp文件 application.yml
spring:
mvc:
view:
prefix: /
suffix: .jsp
然后就是idea调整以下设置,我也不太明白图中这个设置具体是干什么的,不过你不这设置就找不到jsp文件,也就是说找jsp文件的时候不会去webapp目录下面去找。
数据库脚本
- sys_dept 部门表
- sys_resource 资源表
- sys_role 角色表
- sys_role_resource 角色和资源的中间表
- sys_user 用户表
- sys_user_role 角色和用户中间表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_dept
-- ----------------------------
DROP TABLE IF EXISTS `sys_dept`;
CREATE TABLE `sys_dept` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '部门名称',
`parent_id` int(11) DEFAULT NULL COMMENT '上级部门ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for sys_resource
-- ----------------------------
DROP TABLE IF EXISTS `sys_resource`;
CREATE TABLE `sys_resource` (
`resource_id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL COMMENT '父资源ID,一级资源ID为0',
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源名称',
`path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '菜单URL',
`permission` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '授权(多个用逗号分隔,如:user:list,user:create)',
`type` int(11) NOT NULL COMMENT '类型 -1:根目录 0:目录 1:菜单 2:按钮',
`icon` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '资源图标',
`order_num` int(11) DEFAULT 0 COMMENT '排序',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0),
PRIMARY KEY (`resource_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 67 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '菜单管理' ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_resource
-- ----------------------------
INSERT INTO `sys_resource` VALUES (1, 0, '系统管理', '0/1', '', 'content:sys', 0, 'fa fa-cog', 2, '2019-10-30 00:16:24', '2019-11-06 03:39:43');
INSERT INTO `sys_resource` VALUES (2, 1, '用户管理', '0/1/2', 'sys/user', 'sys:user:menu', 1, '', 1, '2019-10-30 00:16:24', '2019-11-06 03:52:30');
INSERT INTO `sys_resource` VALUES (3, 1, '角色管理', '0/1/3', 'sys/role', 'sys:role:menu', 1, '', 2, '2019-10-30 00:16:24', '2019-11-06 03:52:37');
INSERT INTO `sys_resource` VALUES (4, 1, '资源管理', '0/1/4', 'sys/resource', 'sys:resource:menu', 1, '', 3, '2019-10-30 00:16:24', '2019-11-06 03:52:42');
INSERT INTO `sys_resource` VALUES (15, 2, '查询用户', '0/1/2/15', '', 'sys:user:list', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:56:36');
INSERT INTO `sys_resource` VALUES (16, 2, '新增用户', '0/1/2/16', '', 'sys:user:add', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:49:43');
INSERT INTO `sys_resource` VALUES (17, 2, '修改用户', '0/1/2/17', '', 'sys:user:update', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:49:54');
INSERT INTO `sys_resource` VALUES (18, 2, '删除用户', '0/1/2/18', '', 'sys:user:delete', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:50:00');
INSERT INTO `sys_resource` VALUES (19, 3, '查询角色', '0/1/3/19', '', 'sys:role:list', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:57:02');
INSERT INTO `sys_resource` VALUES (20, 3, '新增角色', '0/1/3/20', '', 'sys:role:add', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:57:11');
INSERT INTO `sys_resource` VALUES (21, 3, '修改角色', '0/1/3/21', '', 'sys:role:update', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:57:17');
INSERT INTO `sys_resource` VALUES (23, 4, '查询资源', '0/1/4/23', '', 'sys:resource:list', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:58:38');
INSERT INTO `sys_resource` VALUES (24, 4, '新增资源', '0/1/4/24', '', 'sys:resource:add', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:58:43');
INSERT INTO `sys_resource` VALUES (25, 4, '修改资源', '0/1/4/25', '', 'sys:resource:update', 2, '', 0, '2019-10-30 00:16:24', '2019-11-05 23:00:39');
INSERT INTO `sys_resource` VALUES (26, 4, '删除资源', '0/1/4/26', '', 'sys:resource:delete', 2, '', 0, '2019-10-30 00:16:24', '2019-11-05 23:00:42');
INSERT INTO `sys_resource` VALUES (31, 1, '部门管理', '0/1/31', 'sys/dept', 'sys:dept:menu', 1, '', 4, '2019-10-30 00:16:24', '2019-11-06 03:52:47');
INSERT INTO `sys_resource` VALUES (32, 31, '查询部门', '0/1/31/32', '', 'sys:dept:list', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:58:55');
INSERT INTO `sys_resource` VALUES (33, 31, '新增部门', '0/1/31/33', '', 'sys:dept:add', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:59:01');
INSERT INTO `sys_resource` VALUES (34, 31, '修改部门', '0/1/31/34', '', 'sys:dept:update', 2, '', 0, '2019-10-30 00:16:24', '2019-11-06 00:59:05');
INSERT INTO `sys_resource` VALUES (35, 31, '删除部门', '0/1/31/35', '', 'sys:dept:delete', 2, '', 0, '2019-10-30 00:16:24', '2019-11-05 11:38:00');
INSERT INTO `sys_resource` VALUES (48, 3, '删除角色', '0/1/3/48', '', 'sys:role:delete', 2, '', 0, '2019-11-04 01:09:36', '2019-11-06 00:57:28');
INSERT INTO `sys_resource` VALUES (56, 2, '分配角色', '0/1/2/56', '', 'sys:user:assign:role', 2, '', 0, '2019-11-06 00:50:26', '2019-11-06 00:56:00');
INSERT INTO `sys_resource` VALUES (57, 3, '分配资源', '0/1/3/57', '', 'sys:role:assign:resource', 2, '', 0, '2019-11-06 00:58:01', '2019-11-06 00:58:01');
INSERT INTO `sys_resource` VALUES (61, 0, '主页', '0/61', '', 'content:main', 0, 'fa fa-home', 1, '2019-11-06 03:10:19', '2019-11-06 03:49:27');
INSERT INTO `sys_resource` VALUES (62, 61, '控制台', '0/61/62', '', 'main:console:menu', 1, '', 1, '2019-11-06 03:10:37', '2019-11-06 03:49:19');
INSERT INTO `sys_resource` VALUES (63, 0, '统计分析', '0/63', '', 'content:report', 0, 'fa fa-bar-chart-o', 3, '2019-11-06 03:18:11', '2019-11-06 03:49:45');
INSERT INTO `sys_resource` VALUES (64, 63, '访客统计', '0/63/64', '', 'report:visitor:menu', 1, '', 1, '2019-11-06 03:20:59', '2019-11-06 03:40:39');
INSERT INTO `sys_resource` VALUES (65, 63, '订单统计', '0/63/65', '', 'report:order:menu', 1, '', 2, '2019-11-06 03:22:15', '2019-11-06 03:40:43');
INSERT INTO `sys_resource` VALUES (66, -1, '根节点', '0', NULL, NULL, -1, NULL, NULL, '2019-11-03 19:07:10', '2019-11-04 16:11:21');
-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`role_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称',
`remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
`dept_id` int(20) DEFAULT NULL COMMENT '部门ID',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0),
PRIMARY KEY (`role_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色' ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES (1, 'admin', '系统管理员', NULL, '2019-10-30 01:03:14', '2022-08-31 15:51:53');
INSERT INTO `sys_role` VALUES (2, 'maintenance', '网站运维', NULL, '2019-10-30 01:03:52', '2022-08-31 15:51:57');
-- ----------------------------
-- Table structure for sys_role_resource
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_resource`;
CREATE TABLE `sys_role_resource` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` int(11) NOT NULL COMMENT '角色ID',
`resource_id` int(11) NOT NULL COMMENT '菜单ID',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `role_id`(`role_id`, `resource_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 862 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色与菜单对应关系' ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_role_resource
-- ----------------------------
INSERT INTO `sys_role_resource` VALUES (830, 1, 1);
INSERT INTO `sys_role_resource` VALUES (831, 1, 2);
INSERT INTO `sys_role_resource` VALUES (837, 1, 3);
INSERT INTO `sys_role_resource` VALUES (843, 1, 4);
INSERT INTO `sys_role_resource` VALUES (832, 1, 15);
INSERT INTO `sys_role_resource` VALUES (833, 1, 16);
INSERT INTO `sys_role_resource` VALUES (834, 1, 17);
INSERT INTO `sys_role_resource` VALUES (835, 1, 18);
INSERT INTO `sys_role_resource` VALUES (838, 1, 19);
INSERT INTO `sys_role_resource` VALUES (839, 1, 20);
INSERT INTO `sys_role_resource` VALUES (840, 1, 21);
INSERT INTO `sys_role_resource` VALUES (844, 1, 23);
INSERT INTO `sys_role_resource` VALUES (845, 1, 24);
INSERT INTO `sys_role_resource` VALUES (846, 1, 25);
INSERT INTO `sys_role_resource` VALUES (847, 1, 26);
INSERT INTO `sys_role_resource` VALUES (848, 1, 31);
INSERT INTO `sys_role_resource` VALUES (849, 1, 32);
INSERT INTO `sys_role_resource` VALUES (850, 1, 33);
INSERT INTO `sys_role_resource` VALUES (851, 1, 34);
INSERT INTO `sys_role_resource` VALUES (852, 1, 35);
INSERT INTO `sys_role_resource` VALUES (841, 1, 48);
INSERT INTO `sys_role_resource` VALUES (836, 1, 56);
INSERT INTO `sys_role_resource` VALUES (842, 1, 57);
INSERT INTO `sys_role_resource` VALUES (853, 1, 61);
INSERT INTO `sys_role_resource` VALUES (854, 1, 62);
INSERT INTO `sys_role_resource` VALUES (855, 1, 63);
INSERT INTO `sys_role_resource` VALUES (856, 1, 64);
INSERT INTO `sys_role_resource` VALUES (857, 1, 65);
INSERT INTO `sys_role_resource` VALUES (858, 2, 1);
INSERT INTO `sys_role_resource` VALUES (859, 2, 2);
INSERT INTO `sys_role_resource` VALUES (860, 2, 15);
INSERT INTO `sys_role_resource` VALUES (861, 2, 16);
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
`salt` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '盐',
`email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '邮箱',
`mobile` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机号',
`dept_id` int(20) DEFAULT NULL COMMENT '部门ID',
`status` int(11) NOT NULL DEFAULT 0 COMMENT '状态 0:正常 1:禁用 2:锁定',
`deleted` int(11) NOT NULL DEFAULT 0 COMMENT '0正常 1删除',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0),
PRIMARY KEY (`user_id`) USING BTREE,
UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统用户' ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'admin', '6f89a35fca3ed82005e9ec4ddabc8226', '98C69A2446384F22B5EFC7874095AC69', 'admin@126.com', '13800000000', NULL, 0, 0, '2019-11-05 23:03:24', '2019-11-05 23:04:16');
INSERT INTO `sys_user` VALUES (2, 'jack', '6f89a35fca3ed82005e9ec4ddabc8226', '98C69A2446384F22B5EFC7874095AC69', 'jack@139.com', '18959139189', 1, 0, 0, '2019-10-30 01:05:10', '2019-10-30 15:26:37');
-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`user_id` int(20) NOT NULL COMMENT '用户ID',
`role_id` int(20) NOT NULL COMMENT '角色ID',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `user_id`(`user_id`, `role_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户与角色对应关系' ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES (34, 1, 1);
INSERT INTO `sys_user_role` VALUES (36, 2, 2);
SET FOREIGN_KEY_CHECKS = 1;
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
<!--整合mybatis-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--整合druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!--jsp解析依赖-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
config
遇到过的坑:
- 静态文件js明明显示获取成功http的状态是200,但是这个地方一直报:Uncaught SyntaxError: Unexpected token ‘<‘ 这个错误,后面通过一篇文章终于搞懂了,因为设置了权限控制,必须要把静态引用资源放行,不然就会出现这种问题。
- 使用shiro标签时候@RequiresRoles(“admin”)不起作用,最后查到需要在config里面配置,他这个注解是用的aop。
import com.shiro.test.shiro.ShiroRealm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.apache.shiro.mgt.SecurityManager;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean filterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
Map<String,String> filterMap = new LinkedHashMap();
filterMap.put("/login.jsp","anon");
filterMap.put("/register.jsp","anon");
filterMap.put("/user/*","anon");
filterMap.put("/js/*","anon");
filterMap.put("/**","authc");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(ShiroRealm shiroRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm);
return securityManager;
}
@Bean
public ShiroRealm userRealm(){
ShiroRealm shiroRealm = new ShiroRealm();
return shiroRealm;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
}
自定义Realm
这个地方密码比对是用的md5加密,数据库不可能存明文,我将盐和加密之后的密码都存到数据库中。我可以根据用户名拿到盐和密文密码,那么我将前端传过来的密码再按相同步骤加密一次,如果两个密文是一样,就说明密码是正确的。
import com.shiro.test.mapper.UserMapper;
import com.shiro.test.model.User;
import com.shiro.test.utils.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
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.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
@Slf4j
public class ShiroRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
String password = new String(token.getPassword());
User user = userMapper.getUserInfo(username);
if(user == null) {
throw new UnknownAccountException("用户名不存在");
}
password = MD5Util.md5_private_salt(password,user.getSalt());
if (!user.getPassword().equals(password)) {
throw new CredentialsException("密码错误");
}
if (user.getStatus() == 1) {
throw new DisabledAccountException("账号被禁用");
}
if (user.getStatus() == 2) {
throw new LockedAccountException("账号被锁定");
}
log.info("{}认证成功",username);
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(user, token.getCredentials(), getName());
return info;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
User user = (User) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Set<String> roleNameSet = userMapper.selectUserRoleNameSet(user.getUserId());
info.addRoles(roleNameSet);
Set<String> permissionNameSet = userMapper.selectUserPermissionNameSet(user.getUserId());
Set<String> permissions = new HashSet<>();
for(String name : permissionNameSet) {
for(String permission : name.split(",")){
permissions.add(permission);
}
}
info.addStringPermissions(permissions);
log.info("{}授权完成",user.getUsername());
return info;
}
}
登陆功能开发(简单模拟就行)
login.jsp
<%--
Created by IntelliJ IDEA.
User: 29086
Date: 2022/8/30
Time: 11:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆</title>
<script type="text/javascript" src="/shiro/js/jquery.min.js"></script>
<script type="text/javascript" src="/shiro/js/login.js"></script>
<script type="text/javascript" src="/shiro/js/config.js"></script>
<style type="text/css">
.divForm{
position: absolute;
width: 300px;
height: 200px;
border: 1px solid red;
text-align: center;
top: 50%;
left: 50%;
margin-top: -200px;
margin-left: -150px;
}
</style>
</head>
<body>
<div class="divForm">
<form id="data-form">
<p>
欢迎登陆网站主页
</p>
<p>
用户名:<input type="text" name="username" placeholder="输入用户名"/>
</p>
<p>
密 码:<input type="password" name="password"placeholder="输入密码"/>
</p>
<p><a href="register.jsp">注册</a></p>
<input id="submit" type="button" value="提交"/>
</form>
</div>
</body>
</html>
login.js
$(function () {
$('#submit').bind('click',function () {
$('#data-form').submit();
});
$("#submit").click(function () {
$.ajax({
"url" : httpUrl+"/user/login",
data: $("#data-form").serialize(),
"type" : "post",
"dataType" : "json",
"success" : function(obj) {
if (obj.code == 0) {
window.location.href = 'index.jsp';
} else {
alert(obj.msg);
}
},
"error":function(){
alert("系统错误");
}
});
});
});
登陆之后的主页 index.jsp
<%--
Created by IntelliJ IDEA.
User: 29086
Date: 2022/8/30
Time: 11:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<a href="/shiro/user/logout">退出登陆</a>
<ul>
<li>主页</li>
<ul>
<li>控制台</li>
<li>统计分析</li>
<ul>
<li>访客统计</li>
<li>订单统计</li>
</ul>
<li>系统管理</li>
<ul>
<li>用户管理</li>
<ul>
<li>查询用户</li>
<li>新增用户</li>
<li>修改用户</li>
<li>删除用户</li>
</ul>
<li>角色管理</li>
<ul>
<li>查询角色</li>
<li>新增角色</li>
<li>修改角色</li>
<li>删除角色</li>
</ul>
<li>资源管理</li>
<ul>
<li><a href="/shiro/resource/saveResource">新增资源</a></li>
<li>修改资源</li>
<li>删除资源</li>
<li>分配资源</li>
</ul>
<li>部门管理</li>
<ul>
<li>新增部门</li>
<li>修改部门</li>
<li>删除部门</li>
<li>查询部门</li>
</ul>
</ul>
</ul>
</ul>
</body>
</html>
注册页面 register.jsp
<%--
Created by IntelliJ IDEA.
User: 29086
Date: 2022/8/30
Time: 11:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
<script type="text/javascript" src="/shiro/js/jquery.min.js"></script>
<script type="text/javascript" src="/shiro/js/register.js"></script>
<script type="text/javascript" src="/shiro/js/config.js"></script>
<style type="text/css">
.divForm{
position: absolute;
width: 300px;
height: 200px;
border: 1px solid red;
text-align: center;
top: 50%;
left: 50%;
margin-top: -200px;
margin-left: -150px;
}
</style>
</head>
<body>
<div class="divForm">
<form id="data-form">
<p>
用户注册
</p>
<p>
用户名:<input type="text" name="username" placeholder="输入用户名"/>
</p>
<p>
密 码:<input type="password" name="password"placeholder="输入密码"/>
</p>
<p><a href="login.jsp">不注册,去登陆</a></p>
<input id="submit" type="button" value="提交"/>
</form>
</div>
</body>
</html>
register.js
$(function () {
$('.submit').bind('click',function () {
$('#data-form').submit();
});
$("#submit").click(function () {
$.ajax({
"url" : httpUrl+"/user/register",
data: $("#data-form").serialize(),
"type" : "post",
"dataType" : "json",
"success" : function(obj) {
if (obj.code == 0) {
alert("注册成功");
window.location.href = 'login.jsp';
} else {
alert(obj.msg);
}
},
"error":function(){
alert("系统错误");
}
});
});
});
UserController
import com.shiro.test.model.Result;
import com.shiro.test.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.websocket.server.PathParam;
@Slf4j
@Controller
@RequestMapping("/user")
public class LoginController {
@Autowired
private LoginService loginService;
@PostMapping("/login")
@ResponseBody
public Result login(@PathParam("username") String username,@PathParam("password") String password) {
Result result;
try {
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
Subject subject = SecurityUtils.getSubject();
subject.login(token);
result = Result.ok();
}catch (UnknownAccountException u){
result = Result.error("用户名不存在");
} catch (CredentialsException c){
result = Result.error("账号或密码错误");
}catch (LockedAccountException l){
result = Result.error("账号被禁用");
} catch (DisabledAccountException d){
result = Result.error("账号被锁定");
}
return result;
}
@GetMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/login.jsp";
}
@PostMapping("/register")
@ResponseBody
public Result register(@PathParam("username") String username,@PathParam("password") String password) {
Result result;
try {
result = loginService.register(username,password);
}catch (Exception e){
log.info("注册异常信息:{}",e.getMessage());
result = Result.error("创建账号失败");
}
return result;
}
}
LoginServiceimpl 注册
import com.shiro.test.mapper.UserMapper;
import com.shiro.test.model.Result;
import com.shiro.test.model.User;
import com.shiro.test.model.UserEnum;
import com.shiro.test.service.LoginService;
import com.shiro.test.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.UUID;
@Service
public class LoginServiceimpl implements LoginService {
@Autowired
private UserMapper userMapper;
@Override
public Result register(String username, String password) {
if(username == null || username == ""){
return Result.error("用户名不能为空");
}
if(password == null || password == ""){
return Result.error("密码不能为空");
}
User user = new User();
user.setUsername(username);
String salt = UUID.randomUUID().toString();
String mdePassword = MD5Util.md5_private_salt(password, salt);
user.setPassword(mdePassword);
user.setSalt(salt);
user.setStatus(UserEnum.zero.getNumber());
user.setDeleted(UserEnum.zero.getNumber());
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
userMapper.insertUser(user);
return Result.ok();
}
}
MD5Util
import org.apache.shiro.crypto.hash.Md5Hash;
public class MD5Util {
private static int hashIterations = 3;
private static String public_salt = "958AEF84DB49419689159022A74D547E";
private static String md5_public_salt(String source) {
return new Md5Hash(source, public_salt, hashIterations).toString();
}
public static String md5_private_salt(String source,String salt) {
return new Md5Hash(md5_public_salt(source), salt, hashIterations).toString();
}
}
相关功能差不多了,那就看看演示效果,mybatis相关就不过多描述了,写烂了。 账号密码是admin 123456
已经登陆进来了,那我debug看看是不是对比密文,可以看到数据库和传入的密文是相等的。 注册功能就不多讲了,看代码因该能看懂。
shiro 权限控制 (用的比较多的)
主要分三种
jsp标签形式 先导入再jsp中,可以参考index.jsp
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
判断当前用户是否具有admin角色,如果没有就不显示,有就显示
<shiro:hasRole name="admin"> </shiro:hasRole>
判断当前用户是否有sys:user:add权限,如果没有就不显示,有就显示
<shiro:hasPermission name="sys:user:add"></shiro:hasPermission>
Java 代码方式
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){
log.info("有权限");
}else{
log.info("无权限");
}
Java 注解方式
@Override
public String addResource() {
return "redirect:/index.jsp";
}
相关代码我放百度网盘,需要自取 链接:https://pan.baidu.com/s/1n-e7BSdUmHgLhVvgY-fAYA 提取码:yyds
|