shiro学习(五、springboot+shiro+mybatis+thymeleaf)
入门shiro(感觉成功了)首先感谢狂神,然后我就一本正经的复制代码了
项目结构
运行效果
数据库
- <dependencies>
- <!-- thymeleaf-shiro整合包 -->
- <dependency>
- <groupId>com.github.theborakompanioni</groupId>
- <artifactId>thymeleaf-extras-shiro</artifactId>
- <version>2.0.0</version>
- </dependency>
- <!--快速生成pojo的方法有关的lombok-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.16.10</version>
- </dependency>
- <!-- 引入 myBatis,这是 MyBatis官方提供的适配 Spring Boot 的,而不是Spring Boot自己的-->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.1.0</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.15</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.1.12</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/log4j/log4j -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
- <!--
- Subject 用户,
- SecurityManager 管理所有用户,
- Realm 连接数据,需要自定义
- -->
- <!--shiro整合spring的包-->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.4.0</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <!--thymeleaf模板-->
- <dependency>
- <groupId>org.thymeleaf</groupId>
- <artifactId>thymeleaf-spring5</artifactId>
- </dependency>
- <dependency>
- <groupId>org.thymeleaf.extras</groupId>
- <artifactId>thymeleaf-extras-java8time</artifactId>
- </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>
- ShiroConfig.class
- @Configuration
- public class ShiroConfig {
- //ShiroFilterFactoryBean 第三步
- @Bean
- public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
- ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
- //设置安全管理器
- shiroFilterFactoryBean.setSecurityManager(securityManager);
- /*
- 添加shiro的内置过滤器
- anon:无须认证就可以访问
- authc:必须认证了才可以访问
- perms:拥有对某个资源的权限才能访问
- role:拥有某个角色才可以访问
- */
- Map<String, String> filterMap = new LinkedHashMap();
- // filterMap.put("/user/add","authc");
- // filterMap.put("/user/update","authc");
- filterMap.put("/user/add","perms[user:add]");
- filterMap.put("/user/update","perms[user:update]");
- filterMap.put("/user/*","authc");
- shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
- //设置跳转到登录页面
- shiroFilterFactoryBean.setLoginUrl("/toLogin");
- //设置到未授权页面
- shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");
- return shiroFilterFactoryBean;
- }
- //DefaultWebSecurityManager 第二步
- @Bean(name = "securityManager")
- public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
- DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
- //关联realm
- securityManager.setRealm(userRealm);
- return securityManager;
- }
- //创建realm 域对象,需要自定义 第一步
- @Bean(name = "userRealm")
- public UserRealm getUserRealm(){
- return new UserRealm();
- }
- //shiro 整合thymeleaf
- @Bean
- public ShiroDialect getShiroDialect(){
- return new ShiroDialect();
- }
- }
UserRealm.class
- public class UserRealm extends AuthorizingRealm {
- @Autowired
- private UserService userService;
- @Override //授权
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- System.out.println("-----授权了-----AuthorizationInfo");
- SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
- // info.addStringPermission("user:add");
- //从数据库查权限
- Subject subject = SecurityUtils.getSubject();
- User currentUser = (User) subject.getPrincipal();//其实就是拿认证成功的时候的那个user
- info.addStringPermission(currentUser.getPerms());
- return info;
- }
- @Override //认证
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- System.out.println("-----认证了-----AuthenticationInfo");
- UsernamePasswordToken userToken = (UsernamePasswordToken) token;
- //用户名,密码去数据库取
- User user = userService.queryUserByUsername(userToken.getUsername());
- if (user==null){ //没有这个人
- return null; //其实就是抛出UnknownAccountException异常
- }
- //之后密码认证,shiro 它自己会做
- SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user,user.getPassword(),"");
- Subject currentSubject = SecurityUtils.getSubject();
- Session session = currentSubject.getSession();
- session.setAttribute("loginUser",user);
- return info;
- }
- }
MyController.class
- @Controller
- public class MyController {
- @RequestMapping({"/","/index"})
- public String toIndex(Model model){
- model.addAttribute("msg","hello shiro!!!");
- return "index";
- }
- @RequestMapping("/user/add")
- public String add(){
- return "user/add";
- }
- @RequestMapping("/user/update")
- public String update(){
- return "user/update";
- }
- @RequestMapping("/toLogin")
- public String toLogin(){
- return "login";
- }
- @RequestMapping("/login")
- public String login(String username,String password,Model model){
- //获取当前输入的用户
- Subject subject = SecurityUtils.getSubject();
- //封装用户的数据
- UsernamePasswordToken token = new UsernamePasswordToken(username,password);
- //登录,没有异常就说明登录成功
- try {
- subject.login(token);
- return "index";
- } catch (UnknownAccountException e) {
- model.addAttribute("msg","用户名错误");
- return "login";
- }catch (IncorrectCredentialsException e){
- model.addAttribute("msg","密码错误");
- return "login";
- }
- }
- //没授权
- @RequestMapping("/noauth")
- @ResponseBody
- public String unauthorized(){
- return "没经授权无法进入";
- }
- //退出
- @RequestMapping("/logout")
- public String logout(){
- Subject currentUser = SecurityUtils.getSubject();
- currentUser.logout();
- System.out.println("退出了");
- return "login";
- }
- }
User.class
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class User {
- private int id;
- private String username;
- private String password;
- private String perms;
- }
UserMapper.class
- @Mapper
- @Repository
- public interface UserMapper {
- public User queryUserByUsername(String username);
- }
UserService.class
- public interface UserService {
- public User queryUserByUsername(String username);
- }
UserServiceImpl.class
- @Service
- public class UserServiceImpl implements UserService {
- @Autowired
- private UserMapper userMapper;
- @Override
- public User queryUserByUsername(String username) {
- return userMapper.queryUserByUsername(username);
- }
- }
UserMapper.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.kuang.mapper.UserMapper">
- <select id="queryUserByUsername" parameterType="String" resultType="User">
- select * from user where username=#{username}
- </select>
- </mapper>
application.properties
- mybatis.type-aliases-package=com.kuang.pojo
- mybatis.mapper-locations=classpath:mapper/*.xml
application.yml
- spring:
- datasource:
- username: root
- password: root
- #?serverTimezone=UTC解决时区的报错
- url: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
- driver-class-name: com.mysql.jdbc.Driver
- type: com.alibaba.druid.pool.DruidDataSource
- #Spring Boot 默认是不注入这些属性值的,需要自己绑定
- #druid 数据源专有配置
- initialSize: 5
- minIdle: 5
- maxActive: 20
- maxWait: 60000
- timeBetweenEvictionRunsMillis: 60000
- minEvictableIdleTimeMillis: 300000
- validationQuery: SELECT 1 FROM DUAL
- testWhileIdle: true
- testOnBorrow: false
- testOnReturn: false
- poolPreparedStatements: true
- #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
- #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
- #则导入 log4j 依赖即可,Maven 地址: https://mvnrepository.com/artifact/log4j/log4j
- filters: stat,wall,log4j
- maxPoolPreparedStatementPerConnectionSize: 20
- useGlobalDataSourceStat: true
- connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
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>shiro</title>
- </head>
- <body>
- <h1>首页</h1>
- <div th:if="${session.loginUser==null}">
- <a th:href="@{/toLogin}">登录</a>
- </div>
- <p th:text="${msg}"></p>
- <hr/>
- <div shiro:hasPermission="user:add">
- <a th:href="@{/user/add}">add</a>
- </div>
- <div shiro:hasPermission="user:update">
- <a th:href="@{/user/update}">update</a>
- </div>
- <div th:if="${session.loginUser}">
- <p><a th:href="@{/logout}">退出</a></p>
- </div>
- </body>
- </html>
login.html
- <!DOCTYPE html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- <title>shiro登录</title>
- </head>
- <body>
- <div>
- <p th:text="${msg}" style="color: red"></p>
- <form method="get" th:action="@{/login}">
- <p>用户名:<input type="text" name="username"></p>
- <p>密 码:<input type="text" name="password"></p>
- <p><input type="submit" value="登录"></p>
- </form>
- </div>
- </body>
- </html>
add.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>增加</title>
- </head>
- <body>
- <h2>add</h2>
- </body>
- </html>
update.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>更新</title>
- </head>
- <body>
- <h2>update</h2>
- </body>
- </html>
总结一下:首先搭建好环境是关键:springboot--》MVC--》mybatis,然后进行shiro的过滤,认证,授权。。。
主要理解好
- ShiroConfig
- ShiroFilterFactoryBean
- setFilterChainDefinitionMap()
- DefaultWebSecurityManager
自定义域 UserRealm 继承 AuthorizingRealm
- AuthorizationInfo SimpleAuthenticationInfo
- AuthenticationInfo SimpleAuthorizationInfo
- UsernamePasswordToken
- SecurityUtils
- getSession()
- getSubject()
- getPrincipal()
- AuthenticationToken
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
shiro学习(五、springboot+shiro+mybatis+thymeleaf)的更多相关文章
- mybatis源码学习(四)--springboot整合mybatis原理
我们接下来说:springboot是如何和mybatis进行整合的 1.首先,springboot中使用mybatis需要用到mybatis-spring-boot-start,可以理解为mybati ...
- 【Shiro学习之一】Shiro入门
一.Shiro Apache Shiro是一个Java安全框架. 1.官网:http://shiro.apache.org/ 2.三个核心组件 Subject:即“当前操作用户”,可以指人.第三方进程 ...
- spring boot 学习(五)SpringBoot+MyBatis(XML)+Druid
SpringBoot+MyBatis(xml)+Druid 前言 springboot集成了springJDBC与JPA,但是没有集成mybatis,所以想要使用mybatis就要自己去集成. 主要是 ...
- Shiro Demo:SpringBoot+Shiro+Druid+MyBatis
访问start.spring.io生成项目: 然后选择依赖: pom.xml: <?xml version="1.0" encoding="UTF-8"? ...
- Shiro学习笔记四(Shiro集成WEB)
这两天由于家里出了点事情,没有准时的进行学习.今天补上之前的笔记 -----没有学不会的技术,只有不停找借口的人 学习到的知识点: 1.Shiro 集成WEB 2.基于角色的权限控制 3.基于权限的控 ...
- SpringBoot学习(五)-->SpringBoot的核心
SpringBoot的核心 1.入口类和@SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的J ...
- shiro系列五、shiro密码MD5加密
Shiro-密码的MD5加密 1.密码的加密 在数据表中存的密码不应该是123456,而应该是123456加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密 ...
- 【Shiro学习之六】shiro编码/加密
apahce shiro:1.6.0 密码存储,应该加密/生成密码摘要存储,而不是存储明文密码. 1.编码/解码Shiro 提供了 base64和 16进制字符串编码/解码的API支持, 方便一些编码 ...
- springboot学习笔记:11.springboot+shiro+mysql+mybatis(通用mapper)+freemarker+ztree+layui实现通用的java后台管理系统(权限管理+用户管理+菜单管理)
一.前言 经过前10篇文章,我们已经可以快速搭建一个springboot的web项目: 今天,我们在上一节基础上继续集成shiro框架,实现一个可以通用的后台管理系统:包括用户管理,角色管理,菜单管理 ...
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
1.前言 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例. 使用技术:SpringBoot.mybatis.shiro.thymeleaf.pagehelp ...
随机推荐
- 数据库 | Redis 缓存雪崩解决方案
Redis 雪崩 缓存层承载着大量的请求,有效保护了存储层.但是如果由于缓存大量失效或者缓存整体不能提供服务,导致大量的请求到达存储层,会使存储层负载增加,这就是缓存雪崩的场景. 解决缓存雪崩,可以从 ...
- js 操作select和option常见用法
1.获取选中select的value和text,html <select id="mySelect"> <option value="1"&g ...
- 深度学习之DCGAN
1.知识点 """ DCGAN:相比GAN而言,使用了卷积网络替代全连接 卷积:256*256*3 --- > 28*28*14 -->结果 ,即H,W变小, ...
- PCD(点云数据)文件格式
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=54 为什么用一种新的文件格式? PCD文件格式并非白费力气地做重复工作,现有 ...
- Java中非静态成员变量、静态成员变量的初始化时机
转: Java中非静态成员变量.静态成员变量的初始化时机. 2018年05月22日 11:48:11 SilenceCarrot 阅读数 421 版权声明:技术就要分享才有意思,欢迎大家分享(注明 ...
- 前端需要掌握的Babel知识
Babel 是怎么工作的 Babel 是一个 JavaScript 编译器. 做与不做 注意很重要的一点就是,Babel 只是转译新标准引入的语法,比如: 箭头函数 let / const 解构 哪些 ...
- postgres serial创建自增列
Sequence是数据库中一类特殊的对象,其用于生成唯一数字标识符.一个典型的应用场景就是手动生成一系列主键.Sequence和MySQL中的AUTO_INCREMENT的概念很像. 创建序列Sequ ...
- 【数学建模】线性规划各种问题的Python调包方法
关键词:Python.调包.线性规划.指派问题.运输问题.pulp.混合整数线性规划(MILP) 注:此文章是线性规划的调包实现,具体步骤原理请搜索具体解法. 本文章的各个问题可能会采用多种调用方 ...
- 阿里云Centos7挂载数据盘
查看磁盘情况 fdisk -l fdisk /dev/vdb 根据提示,分别输入 n. p. . enter.enter.wq fdisk -l mkfs.ext3 /dev/vdb1 挂载磁盘,写入 ...
- Kettle实现从mysql中取2张表数据关联的数据,并写入到mongodb中
1 建立转换,并设置DB连接到mysql 选中DB连接:连接类型选择MySQL,输入主机名称,数据库名称,端口号,用户名,密码 输入连接名称,点击确定.(可以先点击测试,测试一下是否连接成功) 如下图 ...