shiro mysql_springboot + shiro + mysql + mybatis 工程快速搭建

本文介绍了如何在SpringBoot项目中整合Apache Shiro和Thymeleaf,实现用户登录、权限验证以及页面访问控制。通过创建User类、UserService、ShiroConfig以及自定义Realm,配置了Shiro的过滤器链,实现了不同URL的权限访问策略,并提供了登录、登出以及未授权页面的处理。同时,文章还展示了数据库中的用户表结构,用于存储用户信息和权限。
摘要由CSDN通过智能技术生成

1. 新建 springboot 工程

f7f33194d9a8f765b7e11b58f0faa58c.png

2. 随便起个名字

bb337b934d72c292f522235c2a61f710.png

3. 初始化工程

c13a910f20a270f77a7e9fcd41501e03.png

8aa0932b0aa017abcf17452c571a7c72.png

4. 导入 shiro 和 thymeleaf 依赖

8f2fc3b0746dc879c0f9abb0c58540fb.png

org.springframework.boot

spring-boot-starter-thymeleaf

org.apache.shiro

shiro-spring

1.3.2

5. 编写 application.yml 配置文件

efed2d9e8d2d8bddfdd6b67410caf25f.png

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 类

52538638834e15160e297d72ba618e46.png

importlombok.Data;

@Datapublic classUser {privateInteger id;privateString username;privateString password;privateString prems;

}

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

ddf6ebb935ca4dde2062c2ca05697c95.png

UserService

importcom.example.exam01.entity.User;/*** User 业务层*/

public interfaceUserService {

User findByName(String username);

}

UserServiceImpl

importcom.example.exam01.dao.UserDao;importcom.example.exam01.entity.User;importcom.example.exam01.service.UserService;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjavax.annotation.Resource;/*** User 业务层实现类*/@Service

@Transactionalpublic class UserServiceImpl implementsUserService {

@ResourceprivateUserDao userDao;

@OverridepublicUser findByName(String username) {returnuserDao.findByName(username);

}

}

UserDao

importcom.example.exam01.entity.User;importorg.apache.ibatis.annotations.Mapper;importorg.apache.ibatis.annotations.Param;importorg.apache.ibatis.annotations.Select;importorg.springframework.stereotype.Repository;/*** User 持久层*/@Repository

@Mapperpublic interfaceUserDao {

@Select("SELECT * FROM user WHERE username = #{username}")

User findByName(@Param("username") String username);

}

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

e2ccaf9016482f825efbacdf2cdf3b64.png

importcom.example.exam01.shiro.realm.MyRealm;importorg.apache.shiro.mgt.SecurityManager;importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.util.LinkedHashMap;importjava.util.Map;/*** shiro 配置类*/@Configurationpublic classShiroConfig {

@Bean(name= "shiroFilter")publicShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {

ShiroFilterFactoryBean shiroFilterFactoryBean= newShiroFilterFactoryBean();

shiroFilterFactoryBean.setSecurityManager(securityManager);

shiroFilterFactoryBean.setLoginUrl("/toLogin");

shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");//定义一个map集合用来存放访问规则

Map 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);returnshiroFilterFactoryBean;

}/*** 获取 SecurityManager

*@return

*/@BeanpublicSecurityManager securityManager() {

DefaultWebSecurityManager defaultSecurityManager= newDefaultWebSecurityManager();

defaultSecurityManager.setRealm(myRealm());returndefaultSecurityManager;

}/*** 获取 MyRealm

*@return

*/@BeanpublicMyRealm myRealm() {

MyRealm myRealm= newMyRealm();returnmyRealm;

}

}

9. 新建一个 Realm 类

3e3bdeb7a19a69078f55af1c033ae4a1.png

importcom.example.exam01.entity.User;importcom.example.exam01.service.UserService;importorg.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.authz.SimpleAuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;importorg.apache.shiro.subject.Subject;importjavax.annotation.Resource;importjava.util.HashSet;importjava.util.Set;/*** realm类*/

public class MyRealm extendsAuthorizingRealm {

@ResourceprivateUserService userService;/*** 授权

*@paramprincipalCollection

*@return

*/@OverrideprotectedAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//获取当前登录用户

Subject subject =SecurityUtils.getSubject();

User user=(User) subject.getPrincipal();//获取 SimpleAuthorizationInfo 对象写入授权规则

SimpleAuthorizationInfo info = newSimpleAuthorizationInfo();//创建一个 set 集合用来保存当前用户的授权信息

Set stringSet = new HashSet<>();

stringSet.add(user.getPrems());//将授权信息写入 SimpleAuthorizationInfo 对象中

info.setStringPermissions(stringSet);returninfo;

}/*** 认证

*@paramauToken

*@return*@throwsAuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auToken) throwsAuthenticationException {//AuthenticationToken 强转 UsernamePasswordToken

UsernamePasswordToken token =(UsernamePasswordToken) auToken;//从数据库获取用户信息

User user =userService.findByName(token.getUsername());return newSimpleAuthenticationInfo(user, user.getPassword(),getName());

}

}

10. 编写 controller 层

715a8291edc6952c68cf470a5d24c3ec.png

LoginController

packagecom.example.exam01.controller;importcom.example.exam01.entity.User;importorg.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;importorg.apache.shiro.crypto.hash.SimpleHash;importorg.apache.shiro.subject.Subject;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.RequestMapping;/*** Login 控制类*/@Controllerpublic classLoginController {//跳转登录页面

@RequestMapping("/toLogin")publicString toLogin(){return "login";

}//执行登录方法

@RequestMapping("/login")publicString 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 = newUsernamePasswordToken(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")publicString logout(){

Subject subject=SecurityUtils.getSubject();

subject.logout();return "login";

}//跳转错误页面

@RequestMapping("/noAuth")publicString noAuth(){return "noAuth";

}

}

UserController

importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;

@Controller

@RequestMapping("/user")public classUserController {

@RequestMapping("list")publicString list(){return "/user/userList";

}

}

AdminController

importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;

@Controller

@RequestMapping("/admin")public classAdminController {

@RequestMapping("/list")publicString list(){return "/admin/adminList";

}

}

11. 编写 HTML 页面

b29b94efae39c01b18b4747298ec8c21.png

login.html

登录

账号:

密码:

main.html

主页

退出登录


UserList

AdminList

noAuth.html

错误页面

adminList.html

AdminList

userList.html

UserList

12. 编写数据库

53e8868b1f121af9a855d7cd18f3126a.png

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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值