日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

SpringBoot 整合 Shiro Thymeleaf Mysql 动态授权

發(fā)布時(shí)間:2024/9/27 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot 整合 Shiro Thymeleaf Mysql 动态授权 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 需求安排
  • 一、前期準(zhǔn)備
    • 1. maven依賴(lài)
    • 2. 創(chuàng)建數(shù)據(jù)庫(kù)+初始化表數(shù)據(jù)
    • 3. 實(shí)體類(lèi)
    • 4. mapper接口
    • 5. mapper接口映射文件
    • 6. service接口
    • 7. service實(shí)現(xiàn)類(lèi)
    • 8. 首頁(yè)控制器
    • 9. 用戶(hù)控制器
    • 10. 全局配置文件
    • 11. 啟動(dòng)類(lèi)加注解
  • 二、頁(yè)面準(zhǔn)備
    • 2.1. 首頁(yè)頁(yè)面
    • 2.2. 登錄頁(yè)面
    • 2.3. 未授權(quán)頁(yè)面
    • 2.4. 用戶(hù)添加頁(yè)面
    • 2.5. 用戶(hù)更新頁(yè)面
  • 三、Shiro 配置
    • 3.1. 自定義UserRealm
    • 3.2. ShiroConfig
  • 四、需求測(cè)試
  • 五、源碼鏈接

需求安排

需求分析: 1. 匿名允許訪(fǎng)問(wèn)頁(yè)面首頁(yè)和登錄頁(yè)面 2. 默認(rèn)登錄頁(yè)面 3. admin用戶(hù)只有用戶(hù)添加權(quán)限 4. test用戶(hù)只有用戶(hù)更新權(quán)限 5. 訪(fǎng)問(wèn)授權(quán)頁(yè)面,默認(rèn)跳轉(zhuǎn)登錄頁(yè)面 6. 登錄認(rèn)證通過(guò),訪(fǎng)問(wèn)無(wú)權(quán)限頁(yè)面,默認(rèn)跳轉(zhuǎn)未授權(quán)頁(yè)面 7. 登錄認(rèn)證通過(guò),進(jìn)行資源授權(quán)角色授權(quán)后,訪(fǎng)問(wèn)各自有權(quán)限的頁(yè)面 注:第6條企業(yè)內(nèi)部采用無(wú)權(quán)限的頁(yè)面采用shiro和頁(yè)面整合策略,直接不會(huì)顯示

一、前期準(zhǔn)備

1. maven依賴(lài)

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><druid.version>1.0.28</druid.version><mybatis-spring-boot.version>2.1.2</mybatis-spring-boot.version><shiro-spring.version>1.5.2</shiro-spring.version><thymeleaf-extras-shiro.version>2.0.0</thymeleaf-extras-shiro.version></properties><dependencies><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--thymeleaf模板引擎--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--springMvc啟動(dòng)器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- shiro與spring整合依賴(lài) --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro-spring.version}</version></dependency><!--mybatis啟動(dòng)器--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis-spring-boot.version}</version></dependency><!--MYSQL--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- 集成druid數(shù)據(jù)源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><!-- thymel對(duì)shiro的擴(kuò)展坐標(biāo) --><dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>${thymeleaf-extras-shiro.version}</version></dependency></dependencies>

2. 創(chuàng)建數(shù)據(jù)庫(kù)+初始化表數(shù)據(jù)

數(shù)據(jù)庫(kù)名:shiro
表名:user

DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶(hù)id',`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用戶(hù)名',`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密碼',`perms` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '授權(quán)字段',PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'admin', 'admin', 'user:add'); INSERT INTO `user` VALUES (2, 'test', 'test', 'user:update');

3. 實(shí)體類(lèi)

package com.gblfy.entity;import lombok.Data; import java.io.Serializable;@Data public class User implements Serializable {private Integer id;private String name;private String password;private String perms; }

4. mapper接口

package com.gblfy.mapper;import com.gblfy.entity.User;public interface UserMapper {/*** 通過(guò)id查詢(xún)用戶(hù)信息** @param id* @return*/User selectByPrimaryKey(Integer id);/*** 根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息** @param name* @return*/User selectByName(String name);}

5. mapper接口映射文件

在resources目錄下面創(chuàng)建mapping文件夾

<?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.gblfy.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.gblfy.entity.User"><id column="id" property="id" jdbcType="INTEGER"/><result column="name" property="name" jdbcType="VARCHAR"/><result column="password" property="password" jdbcType="VARCHAR"/><result column="perms" property="perms" jdbcType="VARCHAR"/></resultMap><sql id="Base_Column_List">id, name, password, perms</sql><select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">select<include refid="Base_Column_List"/>from userwhere id = #{id,jdbcType=INTEGER}</select><select id="selectByName" resultMap="BaseResultMap" parameterType="java.lang.String">select<include refid="Base_Column_List"/>from userwhere name = #{name,jdbcType=VARCHAR}</select> </mapper>

6. service接口

package com.gblfy.service;import com.gblfy.entity.User;public interface UserService {/*** 根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息** @param name* @return*/User selectByName(String name);/*** 通過(guò)id查詢(xún)用戶(hù)信息** @param id* @return*/User selectByPrimaryKey(Integer id); }

7. service實(shí)現(xiàn)類(lèi)

package com.gblfy.service.impl;import com.gblfy.entity.User; import com.gblfy.mapper.UserMapper; import com.gblfy.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;@Service public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;/*** 根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息** @param name* @return*/@Overridepublic User selectByName(String name) {return userMapper.selectByName(name);}/*** 通過(guò)id查詢(xún)用戶(hù)信息** @param id* @return*/@Overridepublic User selectByPrimaryKey(Integer id) {return userMapper.selectByPrimaryKey(id);}}

8. 首頁(yè)控制器

package com.gblfy.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class IndexController {@RequestMapping("index")public String index() {return "index";} }

9. 用戶(hù)控制器

package com.gblfy.controller;import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class UserController {//跳轉(zhuǎn)登錄頁(yè)面@RequestMapping("/toLogin")public String toLogin() {return "login";}//用戶(hù)添加@RequestMapping("/add")public String add() {return "/user/add";}//用戶(hù)更新@RequestMapping("/update")public String update() {return "/user/update";}//未授權(quán)跳轉(zhuǎn)頁(yè)面@RequestMapping("noAuth")public String noAuth() {return "noAuth";}//登錄處理@RequestMapping("login")public String login(String username, String password, Model model) {/*** 編寫(xiě)shiro認(rèn)證操作* 1.獲取subject* 2.封裝用戶(hù)數(shù)據(jù)* 3.執(zhí)行登錄方法*///1.獲取subjectSubject subject = SecurityUtils.getSubject();//2.封裝用戶(hù)數(shù)據(jù) 認(rèn)證時(shí)會(huì)用到UsernamePasswordToken token = new UsernamePasswordToken(username, password);//3.執(zhí)行登錄方法try {subject.login(token);//登陸成功} catch (UnknownAccountException e) {e.printStackTrace();//登陸失敗 場(chǎng)景1model.addAttribute("msg", "用戶(hù)名不存在!");return "login";} catch (IncorrectCredentialsException e) {e.printStackTrace();//登陸失敗 場(chǎng)景2model.addAttribute("msg", "密碼錯(cuò)誤!");return "login";}//登陸成功model.addAttribute("msg", username + "登陸成功跳轉(zhuǎn)首頁(yè)");return "index";} }

10. 全局配置文件

#server 端口 server:port: 80tomcat:min-spare-threads: 30max-threads: 1000#Mysql配置 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/shiro?useSSL=true&serverTimezone=GMT&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8username: rootpassword: roottype: com.alibaba.druid.pool.DruidDataSource# Mybatis Mapper映射文件+實(shí)體類(lèi)配置 mybatis:type-aliases-package: com.gblfy.entitymapperLocations:- classpath*:/mapping/*.xml

11. 啟動(dòng)類(lèi)加注解

package com.gblfy;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication @MapperScan("com.gblfy.mapper") public class SpringbootShiroApplication {public static void main(String[] args) {SpringApplication.run(SpringbootShiroApplication.class, args);}}

二、頁(yè)面準(zhǔn)備

2.1. 首頁(yè)頁(yè)面

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"><head><meta charset="UTF-8"><title>系統(tǒng)首頁(yè)</title> </head> <body> <h3 th:text="${msg}" style="color: red"></h3> <div>進(jìn)入用戶(hù)添加頁(yè)面:&ensp;&ensp;&ensp;<a href="/add">用戶(hù)添加</a> </div> <br/> <div>進(jìn)入用戶(hù)更新頁(yè)面:&ensp;&ensp;&ensp;<a href="/update">用戶(hù)更新</a> </div> </body> </html>

2.2. 登錄頁(yè)面

<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>登錄頁(yè)面</title> </head> <body> <h3 th:text="${msg}" style="color: red">登錄</h3> <form method="post" action="/login">用戶(hù)名:<input type="text" name="username"/><br/>&ensp;碼:<input type="password" name="password"/><br/><input type="submit" value="登錄"/> </form> </body> </html>

2.3. 未授權(quán)頁(yè)面

<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>未授權(quán)頁(yè)面</title> </head> <body> 未授權(quán)頁(yè)面,請(qǐng)聯(lián)系管理員進(jìn)行授權(quán)操作! </body> </html>

2.4. 用戶(hù)添加頁(yè)面

<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>添加頁(yè)面</title> </head> <body> <h3>添加頁(yè)面</h3> </body> </html>

2.5. 用戶(hù)更新頁(yè)面

<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>更新頁(yè)面</title> </head> <body> <h3>更新頁(yè)面</h3> </body> </html>

三、Shiro 配置

3.1. 自定義UserRealm

package com.gblfy.realm;import com.gblfy.entity.User; import com.gblfy.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 org.springframework.beans.factory.annotation.Autowired;/*** 自定義 UserRealm* 固定寫(xiě)法:extends AuthorizingRealm*/ public class UserRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;/*** 認(rèn)證** @param token* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1.得到用戶(hù)名和密碼 因?yàn)榈卿浺汛?#xff0c;因此,能取UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;String username = usernamePasswordToken.getUsername();//默認(rèn)獲取password的類(lèi)型為char[],轉(zhuǎn)換處理String password = new String(usernamePasswordToken.getPassword());//2.從數(shù)據(jù)庫(kù)根據(jù)用戶(hù)名查詢(xún)用戶(hù)信息User user = userService.selectByName(username);//判斷查詢(xún)出的用戶(hù)對(duì)象(sysUser)是否為空if (user == null) {throw new UnknownAccountException("用戶(hù)不存在!");}//判斷查詢(xún)出的用戶(hù)對(duì)象的用戶(hù)密碼和頁(yè)面從頁(yè)面?zhèn)鬟f過(guò)來(lái)的密碼進(jìn)行比較是否相同if (!user.getPassword().equals(password)) {throw new IncorrectCredentialsException("密碼有誤!");}//認(rèn)證通過(guò) 登陸成功SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());return info;}/*** 授權(quán)** @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//通過(guò)id用戶(hù)信息Subject subject = SecurityUtils.getSubject();//認(rèn)證時(shí)存的是user,因此可以強(qiáng)轉(zhuǎn)成user對(duì)象User user = (User) subject.getPrincipal();User userPerms = userService.selectByPrimaryKey(user.getId());//從user對(duì)象動(dòng)態(tài)獲取權(quán)限,放到認(rèn)證容器info.addStringPermission(userPerms.getPerms());return info;}}

3.2. ShiroConfig

package com.gblfy.config;import com.gblfy.realm.UserRealm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap; import java.util.Map;@Configuration public class ShiroConfig {/*** 1.創(chuàng)建Realm*/@Bean(name = "userRealm")public UserRealm getRealm() {return new UserRealm();}/*** 2.創(chuàng)建DefaultWebSecurityManager*/@Bean(name = "securityManager")public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();//關(guān)聯(lián)realmsecurityManager.setRealm(userRealm);return securityManager;}/*** 3.創(chuàng)建ShiroFilterFactoryBean*/@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//設(shè)置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//指定登錄頁(yè)面shiroFilterFactoryBean.setLoginUrl("/toLogin");//指定未授權(quán)頁(yè)面shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");//添加Shiro內(nèi)置過(guò)濾器/*** Shiro內(nèi)置過(guò)濾器,可以實(shí)現(xiàn)權(quán)限相關(guān)的攔截器* 常用的過(guò)濾器:* anon: 無(wú)需認(rèn)證(登錄)可以訪(fǎng)問(wèn)* authc: 必須認(rèn)證才可以訪(fǎng)問(wèn)* user: 如果使用rememberMe的功能可以直接訪(fǎng)問(wèn)* perms: 該資源必須得到資源權(quán)限才可以訪(fǎng)問(wèn)* role: 該資源必須得到角色權(quán)限才可以訪(fǎng)問(wèn)*/Map<String, String> filterMap = new LinkedHashMap<String, String>();//設(shè)置允許匿名訪(fǎng)問(wèn)filterMap.put("/index", "anon");filterMap.put("/login", "anon");//配置授權(quán)過(guò)濾器 第一種filterMap.put("/add", "perms[user:add]");filterMap.put("/update", "perms[user:update]");//授權(quán)才可以訪(fǎng)問(wèn)filterMap.put("/*", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);return shiroFilterFactoryBean;}}

四、需求測(cè)試

測(cè)試計(jì)劃; 1. 訪(fǎng)問(wèn)http://localhost/index和http://localhost/login 是否可以匿名訪(fǎng)問(wèn) 2. 訪(fǎng)問(wèn)http://localhost/index頁(yè)面,點(diǎn)擊進(jìn)入添加頁(yè)面是否跳轉(zhuǎn)登錄頁(yè)面 3. 訪(fǎng)問(wèn)http://localhost/index頁(yè)面,點(diǎn)擊進(jìn)入更新頁(yè)面是否跳轉(zhuǎn)登錄頁(yè)面 4. 訪(fǎng)問(wèn)幾個(gè)不存在的url測(cè)試是否默認(rèn)統(tǒng)一跳轉(zhuǎn)登錄頁(yè)面。例如: http://localhost/xxx 5. 使用admin賬戶(hù),訪(fǎng)問(wèn)登錄頁(yè)面,做一下測(cè)試:1>輸入不存在的賬戶(hù)點(diǎn)擊登錄,不輸密碼,測(cè)試,是否提示用戶(hù)名不存在2>輸入存在的賬戶(hù)admin不輸密碼,點(diǎn)擊登錄,測(cè)試,是否提示密碼錯(cuò)誤3>輸入存在的正確的賬戶(hù)admin,輸入正確的密碼,點(diǎn)擊登錄,測(cè)試,點(diǎn)擊用戶(hù)添加,是否可以進(jìn)入用戶(hù)添加頁(yè)面4>輸入存在的正確的賬戶(hù)admin,輸入正確的密碼,點(diǎn)擊登錄,測(cè)試,點(diǎn)擊用戶(hù)更新,是否跳轉(zhuǎn)未授權(quán)頁(yè)面 6. 使用test賬戶(hù),訪(fǎng)問(wèn)登錄頁(yè)面,做一下測(cè)試:1>輸入不存在的賬戶(hù)點(diǎn)擊登錄,不輸密碼,測(cè)試,是否提示用戶(hù)名不存在2>輸入存在的賬戶(hù)test不輸密碼,點(diǎn)擊登錄,測(cè)試,是否提示密碼錯(cuò)誤3>輸入存在的正確的賬戶(hù)test,輸入正確的密碼,點(diǎn)擊登錄,測(cè)試,點(diǎn)擊用戶(hù)更新,是否可以進(jìn)入用戶(hù)更新頁(yè)面4>輸入存在的正確的賬戶(hù)test,輸入正確的密碼,點(diǎn)擊登錄,測(cè)試,點(diǎn)擊用戶(hù)添加,是否跳轉(zhuǎn)未授權(quán)頁(yè)面

到此,除了成功登錄后,角色授權(quán),就都演示完了!

五、源碼鏈接

總結(jié)

以上是生活随笔為你收集整理的SpringBoot 整合 Shiro Thymeleaf Mysql 动态授权的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。