如果你对shiro有问题的话,请看这篇文章:Springboot+shiro,完整教程,带你学会shiro-CSDN博客

第一步,先准备数据库:

数据库需要准备三个表,一个user表,一个role表,一个permission表。

user表:

CREATE TABLE `user` (
`id` int NOT NULL,
`username` varchar(100) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

role表:

CREATE TABLE `role` (
`id` int NOT NULL,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

permission表:

CREATE TABLE `permission` (
`id` int NOT NULL,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

然后插入数据:

第一个是user表,第二个是permission表,第三个是role表。大家自己建就是了。

第二步就是创建springboot项目,并操作数据库。

pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>org.tianfan</groupId>
<artifactId>shiroTest</artifactId>
<version>1.0-SNAPSHOT</version> <properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.9.1</version>
</dependency> <!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>3.0.0</version>-->
<!-- </dependency>--> <dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.21</version>
<scope>test</scope>
</dependency>
<!-- springbootweb--> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.7</version>
</dependency> <!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency> <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency> </dependencies> </project>

application文件:

spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/tianfan?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC

配置实体类:

user类:

package org.tianfan.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString; import java.io.Serializable; @Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User implements Serializable { private Long id; private String username; private String password; }

Role类:

package org.tianfan.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString; import java.io.Serializable; @Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Role implements Serializable { private Long id; private String name; // getter and setter
}

permission类:

package org.tianfan.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString; import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Permission implements Serializable { private Long id; private String name; // getter and setter
}

准备mapper

PermissionMapper

package org.tianfan.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.tianfan.pojo.Permission; public interface PermissionMapper extends BaseMapper<Permission> {
}

RoleMapper

package org.tianfan.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.tianfan.pojo.Role; public interface RoleMapper extends BaseMapper<Role> {
}

UserMapper

package org.tianfan.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.tianfan.pojo.User;
@Mapper
public interface UserMapper extends BaseMapper<User> { }

准备service

UserService:
package org.tianfan.service;

import org.apache.ibatis.annotations.Mapper;
import org.tianfan.pojo.Permission;
import org.tianfan.pojo.Role;
import org.tianfan.pojo.User; import java.util.List; public interface UserService { User findByUsername(String username); List<Role> findRolesByUserId(Long userId); List<Permission> findPermissionsByRoleId(Long roleId);
}

准备serviceImpl

UserServiceImpl
package org.tianfan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.tianfan.mapper.PermissionMapper;
import org.tianfan.mapper.RoleMapper;
import org.tianfan.mapper.UserMapper;
import org.tianfan.pojo.Permission;
import org.tianfan.pojo.Role;
import org.tianfan.pojo.User;
import org.tianfan.service.UserService; import java.util.ArrayList;
import java.util.List;
@Service
public class UserServiceImpl implements UserService { @Autowired
UserMapper userMapper; @Autowired
RoleMapper roleMapper; @Autowired
PermissionMapper permissionMapper; @Override
public User findByUsername(String username) {
LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper();
lambdaQueryWrapper.eq(User::getUsername,username);
User user = userMapper.selectOne(lambdaQueryWrapper);
System.out.println(user);
return user;
} @Override
public List<Role> findRolesByUserId(Long userId) {
LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper();
lambdaQueryWrapper.eq("id",userId);
Role role = roleMapper.selectOne(lambdaQueryWrapper);
List<Role> list=new ArrayList<>();
list.add(role);
return list;
} @Override
public List<Permission> findPermissionsByRoleId(Long roleId) {
LambdaQueryWrapper lambdaQueryWrapper=new LambdaQueryWrapper();
lambdaQueryWrapper.eq("id",roleId);
Permission permission = permissionMapper.selectOne(lambdaQueryWrapper);
List<Permission> list=new ArrayList<>();
list.add(permission);
return list;
}
}

现在为止,开始配置shiro

配置一下ShiroConfig,配置那些比如说shiro要过滤的请求,securityManager(管理shiro对象的类)拿到主体的关键类,MyShiroRealm认证规格类,LifecycleBeanPostProcessor,用于在Spring容器中管理Shiro的生命周期。

package org.tianfan.config;

import org.apache.shiro.mgt.SessionsSecurityManager;
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.apache.shiro.mgt.SecurityManager; import java.util.LinkedHashMap;
import java.util.Map; @Configuration
public class ShiroConfig { @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/login.html", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
} @Bean
public SessionsSecurityManager securityManager(MyShiroRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//配置realm
securityManager.setRealm(userRealm);
return securityManager;
} @Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
} @Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
} @Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
} @Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
MyShiroRealm认证规格类:
package org.tianfan.config;

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.springframework.beans.factory.annotation.Autowired;
import org.tianfan.service.UserService;
import org.tianfan.pojo.Permission;
import org.tianfan.pojo.Role;
import org.tianfan.pojo.User;
import org.tianfan.service.impl.UserServiceImpl; import java.util.List; public class MyShiroRealm extends AuthorizingRealm { @Autowired
private UserServiceImpl userService; @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User user = (User) principalCollection.getPrimaryPrincipal();
List<Role> roles = userService.findRolesByUserId(user.getId());
for (Role role : roles) {
authorizationInfo.addRole(role.getName());
List<Permission> permissions = userService.findPermissionsByRoleId(role.getId());
for (Permission permission : permissions) {
authorizationInfo.addStringPermission(permission.getName());
}
}
return authorizationInfo;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
System.out.println(token.getUsername());
User user = userService.findByUsername(token.getUsername());
if (user == null) {
throw new UnknownAccountException();
}
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
}

现在就可以测试了,Contoller类:

package org.tianfan.contoller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.tianfan.pojo.User;
import org.tianfan.service.UserService; @RestController
public class UserController { @Autowired
private UserService userService; @PostMapping("/login")
public String login( String username, String password) {
System.out.println(username+password);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "登录成功";
} catch (AuthenticationException e) {
return "用户名或密码错误";
}
} @GetMapping("/user")
public User getUser() {
Subject subject = SecurityUtils.getSubject();
return (User) subject.getPrincipal();
} @GetMapping("/admin")
public String admin() {
return "admin";
}
}

主类:

package org.tianfan;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
}

前端页面login.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录表单</title>
<style type="text/css">
body {
background-color: #333;
font-family: Arial, sans-serif;
font-size: 14px;
color: #fff;
}
.container {
margin: 0 auto;
width: 400px;
padding: 20px;
background-color: #444;
border-radius: 5px;
box-shadow: 0 0 10px #000;
}
h2 {
margin-top: 0;
text-align: center;
}
form {
display: block;
margin: 0;
padding: 0;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="text"], input[type="password"], input[type="email"] {
display: block;
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: none;
border-radius: 5px;
background-color: #555;
color: #fff;
font-size: 14px;
}
input[type="submit"], input[type="reset"] {
display: inline-block;
padding: 10px 20px;
margin-right: 10px;
border: none;
border-radius: 5px;
background-color: #f00;
color: #fff;
font-size: 14px;
cursor: pointer;
}
input[type="submit"]:hover, input[type="reset"]:hover {
background-color: #c00;
}
.third-party {
margin-top: 20px;
text-align: center;
}
.third-party a {
display: inline-block;
margin-right: 10px;
border-radius: 50%;
background-color: #fff;
color: #000;
font-size: 20px;
line-height: 40px;
width: 40px;
height: 40px;
text-align: center;
text-decoration: none;
transition: all 0.3s ease;
}
.third-party a:hover {
background-color: #000;
color: #fff;
}
</style>
</head>
<body>
<div class="container">
<h2>登录</h2>
<form action="http://localhost:8080/login" method="post" name="login-form">
<label for="username">用户名</label>
<input type="text" id="username" name="username" required>
<label for="password">密码</label>
<input type="password" id="password" name="password" required>
<input type="submit" value="登录">
<input type="reset" value="重置">
</form>
<div class="third-party">
<a href="#">QQ</a>
<a href="#">微信</a>
<a href="#">微博</a>
</div>
</div>
</body>
</html>

运行启动结果图:

输入正确的密码:

之后就可以直接访问

如果没有登录正确的账号信息的话,就不可以访问这个,并且会直接跳转到login.jsp

如果你对shiro有问题的话,请看这篇文章:Springboot+shiro,完整教程,带你学会shiro-CSDN博客

Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个的更多相关文章

  1. springboot+layui 整合百度富文本编辑器ueditor入门使用教程(踩过的坑)

    springboot+layui 整合百度富文本编辑器ueditor入门使用教程(踩过的坑) 写在前面: ​ 富文本编辑器,Multi-function Text Editor, 简称 MTE, 是一 ...

  2. duilib教程之duilib入门简明教程8.完整的自绘标题栏

    看了前面那么多教程,相信对duilib已有基本映像了,我们就快马加鞭,做出一个完整的自绘标题栏吧~    看到下面这个效果图,小伙伴们是不是有点惊呆了呢~O(∩_∩)O~      duilib实现以 ...

  3. hadoop入门学习教程--DKHadoop完整安装步骤

    使用hadoop版本是DKH标准三节点发行版,DKHadoop版本的易用性比较好,环境部署要简单的多,参考此篇安装前请先下载DKHadoop版本,网盘链接:https://pan.baidu.com/ ...

  4. springboot整合ueditor实现图片上传和文件上传功能

    springboot整合ueditor实现图片上传和文件上传功能 写在前面: 在阅读本篇之前,请先按照我的这篇随笔完成对ueditor的前期配置工作: springboot+layui 整合百度富文本 ...

  5. spring-session(二)与spring-boot整合实战

    前两篇介绍了spring-session的原理,这篇在理论的基础上再实战. spring-boot整合spring-session的自动配置可谓是开箱即用,极其简洁和方便.这篇文章即介绍spring- ...

  6. springBoot整合spring security+JWT实现单点登录与权限管理--筑基中期

    写在前面 在前一篇文章当中,我们介绍了springBoot整合spring security单体应用版,在这篇文章当中,我将介绍springBoot整合spring secury+JWT实现单点登录与 ...

  7. SpringBoot整合开发

    1.SpringBoot分模块 分模块就是将一个项目分成多个模块,即maven项目. 1)首先创建一个springboot的项目: 第一步:选择springboot的项目 第二步:填写项目的相关信息, ...

  8. Taurus.MVC 微服务框架 入门开发教程:项目部署:1、微服务应用程序常规部署实现多开,节点扩容。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  9. Taurus.MVC 微服务框架 入门开发教程:项目部署:2、让Kestrel支持绑定多个域名转发,替代Ngnix使用。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  10. Taurus.MVC 微服务框架 入门开发教程:项目部署:3、微服务应用程序版本升级:全站升级和局部模块升级。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

随机推荐

  1. 三维模型OSGB格式轻量化的纹理压缩和质量保持分析

    三维模型OSGB格式轻量化的纹理压缩和质量保持分析 在三维模型应用中,纹理数据是一个重要的部分,可以为模型增加更多的真实感和细节.但是,由于纹理数据通常会占用大量的存储空间和传输带宽,因此,在OSGB ...

  2. Python 潮流周刊#18:Flask、Streamlit、Polars 的学习教程

    你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中三则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...

  3. Java开发面试--nacos专区

    1. Nacos是什么? 请简要介绍Nacos是什么以及它的主要功能和用途. 答: 简介: Nacos是一个开源的.高性能.动态服务发现.配置和服务管理平台,通常用于微服务架构中.Nacos的名称来源 ...

  4. Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法

    Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法 点击封面跳转下载页面 简介 Unity 性能优化Shader分析处理函数:Sha ...

  5. Dami 本地过程调用框架(主打解耦),v0.24 发布

    Dami,专为本地多模块之间通讯解耦而设计(尤其是未知模块.隔离模块.领域模块).零依赖,特适合 DDD. 特点 结合 Bus 与 RPC 的概念,可作事件分发,可作接口调用,可作异步响应. 支持事务 ...

  6. Journey / Solution Set - 「NOIP-S 2020」「Prob. A-C」

    这种东西怎么写啊... Day 1(好像也没有 Day 2 到了 NK 后发现正好可以进门,于是就什么也没有检查的进去了. 进门前问了一下 LYC 之前问过的一个问题,他说没有头绪,然后就没怎么说话了 ...

  7. 在Go中如何实现并发

    Go语言的并发机制是其强大和流行的一个关键特性之一.Go使用协程(goroutines)和通道(channels)来实现并发编程,这使得编写高效且可维护的并发代码变得相对容易.下面是Go的并发机制的详 ...

  8. 时髦称呼:SQL递归"语法糖"的用法

    Oracle函数sys_connect_by_path 详解 语法:Oracle函数:sys_connect_by_path 主要用于树查询(层次查询) 以及 多列转行.其语法一般为:       s ...

  9. C#学习笔记--逻辑语句(分支和循环)

    逻辑语句 条件分支语句 条件分支语句可以让顺序执行的代码逻辑产生分支,满足对应条件地执行对应代码逻辑. IF语句 //IF语句块 int a=5; if(a>0&&a<15 ...

  10. RK3588平台产测之ArmSoM产品低温环境测试

    1. 简介 专栏总目录 ArmSoM团队在产品量产之前都会对产品做几次专业化的功能测试以及性能压力测试,以此来保证产品的质量以及稳定性 优秀的产品都要进行严苛的多次全方位的功能测试以及性能压力测试才能 ...