您好,欢迎访问一九零五行业门户网

怎么用Springboot快速整合shiro安全框架

咱们先来普及一下什么是shiro,shiro原名apache shiro 是一个java 的安全(权限)框架。shiro 可以非常容易的开发出足够好的应用,其不仅可以用在javase环境,也可以用在javaee环境。shiro可以完成,认证,授权,加密,会话管理,web集成,缓存等高级应用。如图看shiro的功能和架构图:
话不多说,springboot整合shiro,咱们直接上代码
pom.xml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.6.11</version> <relativepath/> <!-- lookup parent from repository --> </parent> <groupid>com.example</groupid> <artifactid>demo02</artifactid> <version>0.0.1-snapshot</version> <name>demo02</name> <description>demo02</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupid>org.apache.shiro</groupid> <artifactid>shiro-spring</artifactid> <version>1.4.1</version> </dependency> <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.31</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupid>log4j</groupid> <artifactid>log4j</artifactid> <version>1.2.17</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupid>com.alibaba</groupid> <artifactid>druid</artifactid> <version>1.1.12</version> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <version>1.18.18</version> <scope>compile</scope> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-thymeleaf</artifactid> </dependency> <dependency> <groupid>org.thymeleaf</groupid> <artifactid>thymeleaf</artifactid> </dependency> <dependency> <groupid>org.thymeleaf.extras</groupid> <artifactid>thymeleaf-extras-java8time</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>com.github.theborakompanioni</groupid> <artifactid>thymeleaf-extras-shiro</artifactid> <version>2.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> </plugin> </plugins> </build></project>
然后我们建立一个数据库 /*
navicat mysql data transfer
source server :
source server version : 80030
source host : localhost:3306
source database : mybatis
target server type : mysql
target server version : 80030
file encoding : 65001
date: 2023-03-14 18:00:05
*/
set foreign_key_checks=0;
&ndash; table structure for user
drop table if exists user;
create table user (
id int not null auto_increment,
name varchar(255) default null,
pwd varchar(255) default null,
perms varchar(100) default null,
primary key (id)
) engine=innodb auto_increment=4 default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;
&ndash; records of user
insert into user values (&lsquo;1&rsquo;, &lsquo;qin&rsquo;, &lsquo;d1b129656359e35e95ebd56a63d7b9e0&rsquo;, &lsquo;user:add&rsquo;);
insert into user values (&lsquo;2&rsquo;, &lsquo;hai&rsquo;, &lsquo;123&rsquo;, &lsquo;user:insert&rsquo;);
insert into user values (&lsquo;3&rsquo;, &lsquo;root&rsquo;, &lsquo;d1b129656359e35e95ebd56a63d7b9e0&rsquo;, &lsquo;user:update&rsquo;);
application.yml文件
spring: datasource: username: xxxx password: xxxxxxxxxxxx url: jdbc:mysql://localhost:3306/mybatis driver-class-name: com.mysql.cj.jdbc.driver type: com.alibaba.druid.pool.druiddatasourcemybatis: mapper-locations: classpath:mapper/*tat.slowsqlmillis=500
controller层mycontroller类
package com.example.demo02.controller;import lombok.extern.slf4j.slf4j;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;import org.springframework.web.bind.annotation.requestparam;import org.springframework.web.bind.annotation.responsebody;@controller@slf4jpublic class mycontroller { @requestmapping("/") public string toindex(model model){ model.addattribute("msg","hello,shiro"); return "login"; } @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("/noauth") @responsebody public string noauth(){ return "未经授权不能访问此页面"; } //登录操作 @requestmapping("/login") public string login(string username, string password, @requestparam(defaultvalue = "false")boolean rememberme,model model){//使用shiro,编写认证操作//1. 获取subject subject subject = securityutils.getsubject();//2. 封装用户的数据 usernamepasswordtoken token = new usernamepasswordtoken(username, password,rememberme);//3. 执行登录的方法,只要没有异常就代表登录成功! try { subject.login(token); //登录成功!返回首页 system.out.println("输出认证成功跳转页面"); return "index"; } catch (unknownaccountexception e) { //用户名不存在 model.addattribute("msg","用户名不存在"); return "login"; } catch (incorrectcredentialsexception e) { //密码错误 model.addattribute("msg","密码错误"); return "login"; } }}
pojo层user
package com.example.demo02.pojo;import lombok.allargsconstructor;import lombok.data;import lombok.noargsconstructor;@data@allargsconstructor@noargsconstructorpublic class user { private int id; private string name; private string pwd; private string perms;}
config层配置两个类
第一个类shiroconfig
package com.example.demo02.config;import at.pollux.thymeleaf.shiro.dialect.shirodialect;import org.apache.shiro.authc.credential.hashedcredentialsmatcher;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;//声明为配置类@configurationpublic class shiroconfig { //创建 shirofilterfactorybean @bean public shirofilterfactorybean getshirofilterfactorybean(@qualifier("securitymanager")defaultwebsecuritymanager securitymanager){ shirofilterfactorybean shirofilterfactorybean = new shirofilterfactorybean();//设置安全管理器 shirofilterfactorybean.setsecuritymanager(securitymanager);/*添加shiro内置过滤器,常用的有如下过滤器:anon: 无需认证就可以访问authc: 必须认证才可以访问user: 如果使用了记住我功能就可以直接访问perms: 拥有某个资源权限才可以访问role: 拥有某个角色权限才可以访问*/ */ //进行一个拦截 map<string,string> filtermap = new linkedhashmap<string, string>();// filtermap.put("/user/add","authc");// filtermap.put("/user/update","authc"); //授权// filtermap.put("/user/add","perms[user:add]"); //大家记得注意顺序! 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(); //2创建加密对象,设置相关属性 hashedcredentialsmatcher matcher = new hashedcredentialsmatcher(); //2.1采用md5加密 matcher.sethashalgorithmname("md5"); //2.2迭代加密次数 matcher.sethashiterations(3); //3将加密对象存储到myrealm中 userrealm.setcredentialsmatcher(matcher);//关联realm securitymanager.setrealm(userrealm); return securitymanager; } //创建 realm 对象 @bean public userrealm userrealm(){ return new userrealm(); } //配置shirodialect:方言,用于 thymeleaf 和 shiro 标签配合使用 @bean public shirodialect getshirodialect(){ return new shirodialect(); }}
userrealm
package com.example.demo02.config;import com.example.demo02.pojo.user;import com.example.demo02.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.apache.shiro.util.bytesource;import org.springframework.beans.factory.annotation.autowired;import java.util.list;//自定义得userraelmpublic class userrealm extends authorizingrealm { @autowired userservice userservice; //授权 @override protected authorizationinfo dogetauthorizationinfo(principalcollection principalcollection) { system.out.println("执行了=》授权dogetauthorizationinfo"); simpleauthorizationinfo info=new simpleauthorizationinfo();// info.addstringpermission("user:update"); 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("执行了=>认证逻辑authenticationtoken");//假设数据库的用户名和密码// string name = "root";// string password = "123456";//1.判断用户名 usernamepasswordtoken usertoken = (usernamepasswordtoken)token; //连接真实的数据库 user user= userservice.queryuserbyname(usertoken.getusername());// if(user==null){ return null; } subject subject = securityutils.getsubject(); subject.getsession().setattribute("loginuser",user);//2. 验证密码,我们可以使用一个authenticationinfo实现类simpleauthenticationinfo// shiro会自动帮我们验证!重点是第二个参数就是要验证的密码! return new simpleauthenticationinfo(user, user.getpwd(),bytesource.util.bytes("salt"),"");// if(user !=null){// authenticationinfo info = new simpleauthenticationinfo(// token.getprincipal(),// user.getpwd(),// bytesource.util.bytes("salt"),// token.getprincipal().tostring()// );// return info;// }// return null; }}
service层
先是类userserviceimpl
package com.example.demo02.service;import com.example.demo02.mapper.usermapper;import com.example.demo02.pojo.user;import org.springframework.beans.factory.annotation.autowired;import org.springframework.stereotype.service;@servicepublic class userserviceimpl implements userservice { @autowired usermapper usermapper; @override public user queryuserbyname(string name) { return usermapper.queryuserbyname(name); }}
再是接口userservice
package com.example.demo02.service;import com.example.demo02.pojo.user;public interface userservice { public user queryuserbyname(string name);}
mapper层
接口usermapper
package com.example.demo02.mapper;import com.example.demo02.pojo.user;import org.apache.ibatis.annotations.mapper;import org.apache.ibatis.annotations.param;import org.apache.ibatis.annotations.select;import org.springframework.stereotype.repository;@repository//@mapperpublic interface usermapper { @select("select * from user where name=#{name}") public user queryuserbyname(@param("name") string name);}
再就是前端resources里面的static和templates
后端实现鉴权图
存入数据库的数据为加密文件
以上就是怎么用springboot快速整合shiro安全框架的详细内容。
其它类似信息

推荐信息