1. 新建 springboot 工程

2. 随便起个名字

3. 初始化工程

4. 导入 shiro 和 thymeleaf 依赖

        <!-- thymeleaf依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- thymeleaf依赖结束 -->
<!-- shiro依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- shiro依赖结束 -->

5. 编写 application.yml 配置文件

spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url:
jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=true
  username: root password: root thymeleaf: encoding: UTF-8

6. 新建一个 User 类

import lombok.Data;

@Data
public class User {
private Integer id;
private String username;
private String password;
private String prems;
}

7. 创建 User 业务层与持久层

UserService

import com.example.exam01.entity.User;

/**
* User 业务层
*/
public interface UserService {
User findByName(String username);
}

UserServiceImpl

import com.example.exam01.dao.UserDao;
import com.example.exam01.entity.User;
import com.example.exam01.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; /**
* User 业务层实现类
*/
@Service
@Transactional
public class UserServiceImpl implements UserService { @Resource
private UserDao userDao; @Override
public User findByName(String username) {
return userDao.findByName(username);
}
}

UserDao

import com.example.exam01.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository; /**
* User 持久层
*/
@Repository
@Mapper
public interface UserDao { @Select("SELECT * FROM user WHERE username = #{username}")
User findByName(@Param("username") String username);
}

8. 新建一个 ShiroConfig 配置文件类

import com.example.exam01.shiro.realm.MyRealm;
import org.apache.shiro.mgt.SecurityManager;
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.LinkedHashMap;
import java.util.Map; /**
* shiro 配置类
*/
@Configuration
public class ShiroConfig {
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/toLogin");
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth"); // 定义一个map集合用来存放访问规则
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
/*
Shiro内置过滤器, 可以实现权限相关的拦截器
常用的过滤器:
anon: 无需认证(登录)可以访问
authc: 必须认证才可以访问
user: 使用 rememberMe 的功能可以直接访问
perms: 该资源必须得到资源权限才可以访问
role: 该资源必须得到角色权限才可以访问
*/
// 注意配置顺序
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/admin/**", "perms[user:admin]");
filterChainDefinitionMap.put("/user/**", "authc");
filterChainDefinitionMap.put("/logout", "authc");
//主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
filterChainDefinitionMap.put("/**", "authc");
// 将规则写入 shiroFilterFactoryBean 中
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean; } /**
* 获取 SecurityManager
* @return
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
defaultSecurityManager.setRealm(myRealm());
return defaultSecurityManager;
} /**
* 获取 MyRealm
* @return
*/
@Bean
public MyRealm myRealm() {
MyRealm myRealm = new MyRealm();
return myRealm;
}
}

9. 新建一个 Realm 类

import com.example.exam01.entity.User;
import com.example.exam01.service.UserService;
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 javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set; /**
* realm类
*/
public class MyRealm extends AuthorizingRealm { @Resource
private UserService userService;
/**
* 授权
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取当前登录用户
Subject subject = SecurityUtils.getSubject();
User user = (User) subject.getPrincipal(); // 获取 SimpleAuthorizationInfo 对象写入授权规则
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 创建一个 set 集合用来保存当前用户的授权信息
Set<String> stringSet = new HashSet<>();
stringSet.add(user.getPrems()); // 将授权信息写入 SimpleAuthorizationInfo 对象中
info.setStringPermissions(stringSet);
return info;
} /**
* 认证
* @param auToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auToken) throws AuthenticationException {
// AuthenticationToken 强转 UsernamePasswordToken
UsernamePasswordToken token = (UsernamePasswordToken) auToken;
// 从数据库获取用户信息
User user = userService.findByName(token.getUsername());
return new SimpleAuthenticationInfo(user, user.getPassword(),getName());
}
}

10. 编写 controller 层

LoginController

package com.example.exam01.controller;

import com.example.exam01.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; /**
* Login 控制类
*/ @Controller
public class LoginController { // 跳转登录页面
@RequestMapping("/toLogin")
public String toLogin(){
return "login";
} // 执行登录方法
@RequestMapping("/login")
public String login(User user, Model model){
// 执行加密算法
SimpleHash md5 = new SimpleHash("MD5",user.getPassword(),null,1);
String password = md5.toString(); // 获取 subject 对象
Subject subject = SecurityUtils.getSubject(); // 准备 token 令牌
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),password); // 定义一个返回提示信息容器
String msg = null;
// 执行认证登录
try{
subject.login(token);
} catch (UnknownAccountException uae) {
msg = "未知账户";
} catch (IncorrectCredentialsException ice) {
msg = "密码不正确";
} catch (LockedAccountException lae) {
msg = "账户已锁定";
} catch (ExcessiveAttemptsException eae) {
msg = "用户名或密码错误次数过多";
} catch (AuthenticationException ae) {
msg = "用户名或密码不正确";
} // 判断登录是否成功
if (subject.isAuthenticated()) {
return "main";
} else {
token.clear();
// 写入返回 tips
model.addAttribute("msg",msg);
return "login";
}
} // 执行登出方法
@RequestMapping("/logout")
public String logout(){
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "login";
} // 跳转错误页面
@RequestMapping("/noAuth")
public String noAuth(){
return "noAuth";
}
}

UserController

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("/user")
public class UserController { @RequestMapping("list")
public String list(){
return "/user/userList";
}
}

AdminController

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("/admin")
public class AdminController { @RequestMapping("/list")
public String list(){
return "/admin/adminList";
}
}

11. 编写 HTML 页面

login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h3 th:text="${msg}" style="color: red"></h3>
<form action="/login" method="post">
<label>账号: <input type="text" name="username" placeholder="请输入用户名"></label><br>
<label>密码: <input type="password" name="password" placeholder="请输入密码"></label><br>
<input type="submit" value="登录">
</form>
</body>
</html>

main.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<a href="/logout"><button>退出登录</button></a>
<hr>
<a href="/user/list">UserList</a>
<br>
<a href="/admin/list">AdminList</a>
</body>
</html>

noAuth.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>错误页面</title>
</head>
<body>
您没有此权限!
</body>
</html>

adminList.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AdminList</title>
</head>
<body>
AdminList 只是一个需要 admin 权限才能访问的页面
</body>
</html>

userList.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>UserList</title>
</head>
<body>
UserList 这是一个需要登录才能访问的页面
</body>
</html>

12. 编写数据库

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
`password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
`prems` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '权限',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; INSERT INTO `user` VALUES (1, 'lilei', '202cb962ac59075b964b07152d234b70', 'user:admin');
INSERT INTO `user` VALUES (2, 'hanmeimei', '202cb962ac59075b964b07152d234b70', 'user:user'); SET FOREIGN_KEY_CHECKS = 1;

源码下载: springboot + shiro demo 下载地址

springboot + shiro + mysql + mybatis 工程快速搭建的更多相关文章

  1. springboot学习笔记:11.springboot+shiro+mysql+mybatis(通用mapper)+freemarker+ztree+layui实现通用的java后台管理系统(权限管理+用户管理+菜单管理)

    一.前言 经过前10篇文章,我们已经可以快速搭建一个springboot的web项目: 今天,我们在上一节基础上继续集成shiro框架,实现一个可以通用的后台管理系统:包括用户管理,角色管理,菜单管理 ...

  2. springboot学习笔记:8. springboot+druid+mysql+mybatis+通用mapper+pagehelper+mybatis-generator+freemarker+layui

    前言: 开发环境:IDEA+jdk1.8+windows10 目标:使用springboot整合druid数据源+mysql+mybatis+通用mapper插件+pagehelper插件+mybat ...

  3. springboot学习笔记:10.springboot+atomikos+mysql+mybatis+druid+分布式事务

    前言 上一篇文章我们整合了springboot+druid+mybatis+mysql+多数据源: 本篇文章大家主要跟随你们涛兄在上一届基础上配置一下多数据源情况下的分布式事务: 首先,到底啥是分布式 ...

  4. MyBatis项目快速搭建及MySQL一个Statement支持多条命令参数

    一.简述 本文以笔记的形式,记录一个基本Mybatis项目的使用,方便后期项目使用到相关配置时直接复制使用. 二.项目结构 pom.xml中的依赖 <!-- https://mvnreposit ...

  5. springboot入门(一)--快速搭建一个springboot框架

    原文出处 前言在开始之前先简单介绍一下springboot,springboot作为一个微框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速.敏捷地开发新一代基于Spring框架 ...

  6. Shiro Demo:SpringBoot+Shiro+Druid+MyBatis

    访问start.spring.io生成项目: 然后选择依赖: pom.xml: <?xml version="1.0" encoding="UTF-8"? ...

  7. 简易的CRM系统案例SpringBoot + thymeleaf + MySQL + MyBatis版本

    创建maven项目 pop.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns ...

  8. MySQL基于mysqldump快速搭建从库

    MySQL主从搭建总的来说大致分为3个步骤: 1. 为主从实例添加复制所需参数以及创建复制用的账户 2. 需要 […]

  9. SPRINGBOOT配置MYSQL,MYBATIS,DRUID

    配置 DRUID连接池 MYSQL数据库 MYBATIS持久层框架 添加依赖 <dependency> <groupId>mysql</groupId> <a ...

随机推荐

  1. java最全的获取某个接口或者某个类所有对应的所有实现类和继承类的工具类--反射动态获取、非动态获取、按照路径获取等总结

    我们直接上代码吧,代码中有注释说明. //直接看代码吧 import java.io.File; import java.lang.reflect.Field; import java.net.URL ...

  2. QPNP 8909 8916 充电相关(1)【转】

    最近一直在搞电源管理相关内容,之前是8610的bms,现在8916的bms,发现两者还是有点区别的,8916把对last_ocv_uv的估值算法分装成执行文件,作为服务一直运行. 电源管理方面,应该是 ...

  3. navicat premium 12 破解,本人亲测有效,针对error on decrypt request code的解决方法

    好,废话不多说,直接上步骤: 下载安装Navicat 由于本人信服官网的东西,所以Navicat premium12是在官网上边下载.下载地址:https://www.navicat.com.cn/p ...

  4. java8-10-Stream的终止操作

      Stream的终止操作   * allMatch 是否匹配所有 * anyMatch 是否匹配一个 * noneMatch 是否没有匹配一个 * findFirst 返回第一个   * count ...

  5. java8-05-再探函数式接口

      1.自定义函数式接口  MyFun      传入一个参数    返回一个参数

  6. oracle xmltype + blob + clob

    oracle varchar2最大存储长度为4000,所以当字段长度超限时可尝试存储为blob或xmltype格式 xmltype --1.创建xml表 Create TABLE testxml( i ...

  7. nginx学习(四):nginx处理web请求机制

    worker抢占机制 如下图所示,如果有一个请求,各个work进程会进行争锁.谁抢到是谁的.需要注意Nginx 所有worker进程协同工作的关键(共享内存). [accept_mutex的介绍] 当 ...

  8. LDAP认证

    1.LDAP介绍 LDAP,(Light Directory Access Protocol),基于X.500标准的轻量级目录访问协议,类似于目录服务一样,是一个为查询浏览和搜索的数据库,优势在于他的 ...

  9. HTML连载50-伪元素选择器、清除浮动方式五

    一.伪元素选择器 1.什么是伪元素选择器 伪元素选择器作用给指定标签的内容前面添加一个子元素,或者给指定标签的内容后面添加一个子元素. 2.格式: 标签名称::before{ 属性名称:值: } 给指 ...

  10. spring cloud 2.x版本 Sleuth+Zipkin分布式链路追踪

    前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ...