文章目录

  • Shiro安全框架
    • 一、 入门概述
      • 1.1、Shiro是什么
      • 1.2、为什么使用Shiro
      • 1.3、Shiro与Spring Security的区别
      • 1.4、基本功能
        • 1.4.1、主要功能
        • 1.4.2 、次要功能
      • 1.5、架构原理
    • 二、基本使用
      • 2.1、环境准备
      • 2.2、配置ini文件
      • 2.3、登录认证
        • 2.3.1、登录认证概念
        • 2.3.2、登录认证的流程
        • 2.3.3、登录认证示例
      • 2.4、角色、授权
        • 2.4.1、授权
          • 2.4.1.1、授权方式
          • 2.4.1.2、授权流程
        • 2.4.2、角色
        • 2.4.3、角色授权示例
      • 2.5、密码加密
        • 2.5.1、使用Shiro进行加密
    • 三、Shiro整合SpringBoot
      • 3.1、整合依赖
      • 3.2、yml配置文件
      • 3.3、创建目录结构
      • 3.4、创建数据库
      • 3.5、创建对应的类
      • 3.6、创建Shiro配置类
        • 3.6.1、自定义Shiro配置类
        • 3.6.2、自定义Shiro拦截范围
      • 3.7、测试
      • 3.8、登录认证前端
    • 四、多个Realm登录校验
    • 五、rememberMe功能
      • 5.1、基本流程
      • 5.2、代码实现
        • 5.2.1、设置记住我
        • 5.2.2、配置记住我管理器以及Cookie属性
        • 5.2.3、添加用户过滤器
        • 5.2.4、改造Controller登录接口
        • 5.2.5、改造登陆页面
    • 六、用户登出
      • 6.1、代码实现
    • 七、授权、角色认证
      • 7.1、角色认证
        • 7.1.1、后端接口服务注解:fire::fire::fire:
        • 7.1.2、授权验证-没有角色无法访问
        • 7.1.3、授权验证-有角色
        • 7.1.4、创建角色表
      • 7.2、授权访问
    • 八、自定义异常
    • 九、前端角色权限认证
      • 9.1、引入依赖
    • 十、实现缓存
      • 10.1、缓存工具Ehcache
      • 10.2、Shiro整合Ehcache

Shiro安全框架

一、 入门概述

1.1、Shiro是什么

Apache Shiro 是一款功能强大的且易于使用的Java的安全框架。Shiro可以完成:认证、加密、会话管理、与web集集成等。借助SHiro可以帮助我们快速轻松的保护任何应用程序。

shiro官网:Apache Shiro | Simple. Java. Security.

1.2、为什么使用Shiro

与Shiro的特性密不可分:

  • 易于使用
  • 全面
  • 灵活
  • 强力支持Web
  • 兼容性强
  • 社区支持

1.3、Shiro与Spring Security的区别

  1. SpringSecurity基于Spring开发,项目若使用Spring 可以与SpringSecurity作权限更加方便,而Shiro需要与Spring进行整合

  2. Spring Security功能更加丰富

  3. Spring Security社区资源更加丰富

看到这里,是不是有些人就认为Spring Security功能更发面都比Shiro好,为什么不学习SpringSecurity。有一句话:存在即合理。下面看看Shiro的特点

  1. Shiro的配置和使用比较简单,SpringSecurity使用比较复杂

  2. Shiro的依赖性低,不需要任何的容器与框架,可以独立运行

  3. Shiro不仅仅可以使用在Web端,可以使用在任何的场景。

1.4、基本功能

了解Shiro的功能,我们可以去官网下载一张Shiro的功能结构图来进行补充学习:

1.4.1、主要功能

  1. 认证登录(Authentication)
  2. 授权验证(Authorization)
  3. 会话管理(Session Management)
  4. 密码加密(Cryptography)

1.4.2 、次要功能

  1. Web支持(web support)
  2. 缓存(caching)
  3. 多线程并发验证(Concurrency)
  4. 测试(Testing)
  5. 另外身份登录(Run as)
  6. 记住我(Remember me)

1.5、架构原理

从外部来看Shiro,即从应用程序的角度来观察使用Shiro完成工作

应用程序—>(登录)---->subject(对象)进行身份校验---->安全管理器(SecurityManager)---->Reaim(用户登陆的用户信息)

从内部的架构来看Shiro

二、基本使用

2.1、环境准备

1、Shiro不依赖容器,可以直接利用Maven使用

2、添加依赖

<!-- Shiro依赖 --><dependencies><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.9.0</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency></dependencies>

3、创建Maven工程

结构如下:

2.2、配置ini文件

在创建好的工程的Resources目录下,创建一个shiro.ini文件

[users]
zhangsan=z3
lisi=l4

2.3、登录认证

2.3.1、登录认证概念

(1)身份认证:一般需要提供身份ID等一些表示用户登陆这信息身份的标识,如提供email、用户名\密码来认证

(2)在Shiro中、用户需要提供principals(身份)和credentials(证明)给shiro。从而应用能验证用户身份。

2.3.2、登录认证的流程

  1. 收集用户二点身份/凭证,及如用户名/密码
  2. 调用Subject.login进行登录,如果失败则将得到的相应的AuthenticationException异常,根据异常提示用户登录错误信息,否则登陆成功。
  3. 创建自定义的Realm类,继承org.apache.shiro.realm.AuthenticationRealm类,实现doGetAuthenticationInfo()方法

2.3.3、登录认证示例

创建测试类,获取认证对象,进行登录认证,如下:

public class ShiroRun {@SuppressWarnings("deprecation")public static void main(String[] args) {// 1、获取Shiro初始化 通过ini文件获取用户信息@SuppressWarnings("deprecation")IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");try {// 通过工厂创建SecurityManagerSecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 2、获取Subject对象Subject subject = SecurityUtils.getSubject();// 3、获取外部参数 通过页面获取的用户名和密码 创建token对象AuthenticationToken token = new UsernamePasswordToken("zhangsan", "z31");// 4、完成登录subject.login(token);System.out.println("登陆成功...");} catch (UnknownAccountException e) {// TODO: handle exceptionSystem.out.println("用户名不存在...");} catch (IncorrectCredentialsException e) {// TODO: handle exceptionSystem.out.println("密码错误...");} catch (AuthenticationException e) {System.out.println("登陆失败...");}}
}

登陆成功:

密码错误:

账户错误:

2.4、角色、授权

2.4.1、授权

授权:也叫做访问控制,即在应用中控制谁访问哪些资源授权中需要了解的概念:主体(Subject)资源(Resources)权限(Permission)角色(Role)

  • **主体:**访问应用的用户,用户经授权才可访问指定资源
  • **资源:**在应用中用户可以访问的URL,比如JSP页面,查看/编辑某些权限
  • **权限:**表示在应用中用户能不能访问某个资源(有没有权利去访问某一个资源)

Shiro支持粗粒度的授权(用户模块的所有权限的授权)、也支持细粒度的授权(某个模块下的某个功能,比如查询)

2.4.1.1、授权方式
  1. 编程式授权:通过IF-ELSE授权
if(subject.hasRole("admin")){// 有admin的权限
}else if(subject.hasRole("commons")){// 普通用户的权限
}else{// 没有权限
}
  1. 注解式:通过执行的Java方法上加上注解完成,没有泉下今年的将抛出异常
@RequriesRole("admin")
public void queryALL(){// 具体的业务逻辑
}
  1. JSP/GSP标签,在JSP/GSP页面通过相应的标签完成
<shiro:hasRole name="admin"><input type="button" class="queryAll" name="queryAll" value="查询所有"/>
</shiro:hasRole>
2.4.1.2、授权流程
  1. 首先调用Subject.isPermitted*/hasRole* 接口,其余委托SecurityManager。而SecurityManager接着会委托给Authorizer。
  2. Authorizer是真正的授权者,如果调用isPermitted(“user:view”),其首先会通过PermissionResolver把字符串转化成相应的Permission示例。
  3. 再授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限
    1. Authorizer会判断Realm的角色/权限是否与传过来的匹配,如果有多个Realm,则会委托给ModularRealmAuthorizer进行循环判断,如果匹配如isPermitted*/hasRole*会返回true,否则返回false表示授权失败。

2.4.2、角色

角色:权限的集合(比如说系统管理员、业务人员、普通用户人员等)

2.4.3、角色授权示例

【角色】

在ini文件里配置用户角色的权限信息:

[users]
zhangsan=z3,admin,commons
lisi=l4,commons[roles]
admin=user:insert,user:select
commons=user:select

通过以下方式完成用户角色下权限的判断:

if (subject.isPermitted("user:insert")) {System.out.println("用户有插入权限");
}else {System.out.println("没有insert权限");
}

完整示例:

public class ShiroRun {@SuppressWarnings("deprecation")public static void main(String[] args) {// 1、获取Shiro初始化 通过ini文件获取用户信息@SuppressWarnings("deprecation")IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");try {// 通过工厂创建SecurityManagerSecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 2、获取Subject对象Subject subject = SecurityUtils.getSubject();// 3、获取外部参数 通过页面获取的用户名和密码 创建token对象AuthenticationToken token = new UsernamePasswordToken("lisi", "l4");// 4、完成登录subject.login(token);System.out.println("登陆成功...");// 5、判断用户角色if(subject.hasRole("commons")) {System.out.println("拥有commons角色");}else{System.out.println("没有拥有commons角色");}if (subject.isPermitted("user:insert")) {System.out.println("用户有插入权限");}else {System.out.println("没有insert权限");}} catch (UnknownAccountException e) {// TODO: handle exceptionSystem.out.println("用户名不存在...");} catch (IncorrectCredentialsException e) {// TODO: handle exceptionSystem.out.println("密码错误...");} catch (AuthenticationException e) {System.out.println("登陆失败...");}}
}

注意:使用subject.checkPermission(“user:insert”);没有权限则会抛异常

【授权】

首先现在ini文件里为用户添加相应的角色(zhangsan添加admin、commons角色;lisi添加commons角色)

[users]
zhangsan=z3,admin,commons
lisi=l4,commons

使用以下方式判断角色:

if(subject.hasRole("commons")) {System.out.println("拥有commons角色");}else{System.out.println("没有拥有commons角色");
}

完整示例:

public class ShiroRun {@SuppressWarnings("deprecation")public static void main(String[] args) {// 1、获取Shiro初始化 通过ini文件获取用户信息@SuppressWarnings("deprecation")IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");try {// 通过工厂创建SecurityManagerSecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 2、获取Subject对象Subject subject = SecurityUtils.getSubject();// 3、获取外部参数 通过页面获取的用户名和密码 创建token对象AuthenticationToken token = new UsernamePasswordToken("zhangsan", "z3");// 4、完成登录subject.login(token);System.out.println("登陆成功...");// 5、判断用户角色if(subject.hasRole("commons")) {System.out.println("拥有commons角色");}else{System.out.println("没有拥有commons角色");}} catch (UnknownAccountException e) {// TODO: handle exceptionSystem.out.println("用户名不存在...");} catch (IncorrectCredentialsException e) {// TODO: handle exceptionSystem.out.println("密码错误...");} catch (AuthenticationException e) {System.out.println("登陆失败...");}}
}

2.5、密码加密

在实际的开发中,一些敏感的信息需要加密,比如说用户的密码,shiro内嵌了很多的加密算法

2.5.1、使用Shiro进行加密

public class ShiroMD5 {public static void main(String[] args) {String salt = "salt";// 1、密码明文String password = "z3";// 2、使用MD5加密Md5Hash MD5 = new Md5Hash(password);System.out.println("使用MD5加密后的密码:" + MD5.toHex());// 3、给MD5加盐值 在加密玩的再次拼接一段字符串Md5Hash MD5_2 = new Md5Hash(password, salt);System.out.println("使用MD5(带盐值)加密后的密码:" + MD5_2.toHex());// 3、给MD5加盐值 多次加密Md5Hash MD5_3 = new Md5Hash(password, salt,3);System.out.println("使用MD5(带盐值三次加密)加密后的密码:" + MD5_3.toHex());}
}

三、Shiro整合SpringBoot

3.1、整合依赖

<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><parent><groupId>com.wei</groupId><artifactId>dhcc_ShiroProject</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>dhcc_ShiroSpringBoot</artifactId><properties><java.version>1.8</java.version><spring.shiro.version>1.9.0</spring.shiro.version></properties><dependencies><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><!-- shiro --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>${spring.shiro.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--页面模板依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--热部署依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency><!-- MyBatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency><!-- MySQL --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin>    </plugins></build>
</project>

3.2、yml配置文件

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:mapper/*Mapper.xml
spring:datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/shirodb?characterEncoding=UTF-8&useUnicode=true&useSSL=false&serverTimezone=UTCusername: rootpassword: 123456jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8
shiro: loginUrl: /shiroController/login

3.3、创建目录结构

3.4、创建数据库

打开SqlYog工具创建数据库shirodb

USE `shirodb`;DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键id',`name` varchar(50) DEFAULT NULL COMMENT '用户名',`password` varchar(50) DEFAULT NULL COMMENT '密码',`role_id` bigint DEFAULT NULL COMMENT '角色编号',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

3.5、创建对应的类

【实体类User】

@Data
public class User {private Long id;private String name;private String password;private Long roleId;
}

【respority数据持久层】

@Repository
public interface UserMapper extends BaseMapper<User>{}

采用MyBatis-PLUS的通用Mapper

【Service数据服务层(业务层)】

// 接口
public interface UserService {User getUserInfoByName(String name);
}// 实现类
@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserMapper userMapper;public User getUserInfoByName(String name) {QueryWrapper<User> queryWrapper = new QueryWrapper<User>();queryWrapper.eq("name", name);User user = userMapper.selectOne(queryWrapper);return user;}}

【controller控制层】

@Controller
@RequestMapping("/shiro")
public class UserController {@RequestMapping(value = "/login", method = RequestMethod.GET)@ResponseBodypublic String login(@RequestParam("name") String name, @RequestParam("password") String password) {// 1、获取Subject对象Subject subject = SecurityUtils.getSubject();// 2、 封装请求对象到Token对象UsernamePasswordToken token = new UsernamePasswordToken(name,password);try {// 3、调用Subject的login方法完成登录subject.login(token);return "登陆成功!";} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名不存在...");return "用户名错误,登陆失败";} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误...");return "密码错误,登陆失败!";} catch (AuthenticationException e) {e.printStackTrace();System.out.println("登陆失败...");return "登陆失败";}}
}

【Shiro的自定义授权配置类】

@Component
public class MyShiroRealm extends AuthorizingRealm {@Resourceprivate UserService UserService;/*** 用户的登录信息 自定义授权方法*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stubreturn null;}/*** 自定义登录认证方法 token*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 获取登录用户的信息String name = token.getPrincipal().toString(); // 获取用户名
//      String password = new String((char[]) token.getCredentials()); // 获取密码// 调用业务层的接口获取数据库的用户信息User user = UserService.getUserInfoByName(name);if (user != null) {// 封装数据AuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal().toString(),user.getPassword(),ByteSource.Util.bytes("salt"),token.getPrincipal().toString());return info;}return null;}
}

这里需要继承一下AuthorizingRealm,重写参数为token的方法,实现用户的授权登录功能

3.6、创建Shiro配置类

3.6.1、自定义Shiro配置类

要想实现自定义的Shiro配置类,需要创建一个DefaultSecurityManager的方法,在里面去重新自定义授权功能。

@Configuration
public class ShiroConfig {@Resourceprivate MyShiroRealm shiroRealm;/*** 描述:TODO(这里用一句话描述这个方法的作用) * @Title: 创建默认的安全管理器* @return* @author weiyongpeng* @date  2022年10月3日 上午8:15:52*/@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager() {// 1、创建DefaultWebSecurityManagerDefaultWebSecurityManager manager = new DefaultWebSecurityManager();// 2、创建加密对象 设置加密属性HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();// 3、将加密对象存储到MyShiroRealm 采用MD5 迭代次数3matcher.setHashAlgorithmName("MD5");matcher.setHashIterations(3);shiroRealm.setCredentialsMatcher(matcher);// 4将MyShiroRealm存储到DefaultSecurityManagermanager.setRealm(shiroRealm);// 5、返回DefaultSecurityManagerreturn manager;}
}

3.6.2、自定义Shiro拦截范围

@Bean
public DefaultShiroFilterChainDefinition shiroFilterChainDefinition() {DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition();// 设置不忍证可以访问的资源filter.addPathDefinition("/shiro/login", "anon");filter.addPathDefinition("/login","anon");// 设置需要进行登录才可以访问的拦截范围filter.addPathDefinition("/**", "authc");return filter;
}

3.7、测试

使用APIFOX测试登录

【登陆成功】

【登陆失败】

3.8、登录认证前端

使用Thymeleaf实现前端的登陆页面

【引入依赖】

<!--页面模板依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

【添加配置】

  thymeleaf:cache: falseprefix: classpath:/templates/suffix: .htmlencoding: UTF-8mode: HTML5

【编写页面】

登陆页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body><h1>Shiro登录认证</h1><form th:action="@{/shiro/userLogin}" method="post"><div><label>用户名:</label> <input type="text" name="name"placeholder="请输入用户名:"></div><div><label>用户名:</label> <input type="password" name="password"placeholder="123456"></div><div class="buttonDiv"><input type="reset" value="重置"> <input type="submit" value="登录"></div></form>
</body>
</html>

登陆成功首页

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录首页</title>
</head>
<body>
登陆的用户:<span th:text="${session.user}"></span>
</body>
</html>

登陆失败错误页

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登陆失败错误页面</h1>
<h3>对不起,你在登陆的时候遇到了<span th:text="${errorMsg}"></span>的错误<a th:href="@{/shiro/login}">重新登陆</a>
</h3>
</body>
</html>

修改controller的代码

@RequestMapping(value = "/login",method = RequestMethod.GET)public String login() {return "login";}@RequestMapping(value = "/userLogin", method = RequestMethod.POST)public String userLogin(@RequestParam("name") String name, @RequestParam("password") String password,HttpSession session,Model model) {// 1、获取Subject对象Subject subject = SecurityUtils.getSubject();// 2、 封装请求对象到Token对象UsernamePasswordToken token = new UsernamePasswordToken(name,password);try {// 3、调用Subject的login方法完成登录subject.login(token);// 放入sessionsession.setAttribute("user", token.getPrincipal().toString());return "main";} catch (UnknownAccountException e) {e.printStackTrace();System.out.println("用户名不存在...");model.addAttribute("errorMsg","用户名错误,登陆失败");return "error";} catch (IncorrectCredentialsException e) {e.printStackTrace();System.out.println("密码错误...");model.addAttribute("errorMsg","密码错误,登陆失败!");return "error";} catch (AuthenticationException e) {e.printStackTrace();System.out.println("登陆失败...");model.addAttribute("errorMsg","登陆异常,登陆失败!");return "error";}}

四、多个Realm登录校验

  1. 多个Realm实现原理

当应用程序配置多个Realm时,例如,用户名密码校验,手机号校验,邮箱校验等等。Shiro的ModularRealmAuthentication会使用内部的AuthenticationStarategy组件判断认证是否成功或者谁败。

AuthenticationStrategy是一个无状态的组件,它本身验证尝试中被询问4次(这4次交互所需的任何必须的状态将被作为方法参数)

(1)在所有的Realm被调用之前

(2)在调用Realm的getAuthenticationInfo()方法之前

(3)在调用Realm的getAuthenticationInfo()方法之后

(4)在所有的Realm被调用之后

五、rememberMe功能

Shiro提供了记住我的(Remember Me)功能,用户可以在登陆成功后,下次访问页面无需再次登录仍然可以访问。

5.1、基本流程

  1. 首先在登陆的页面选中Remember Me然后再登陆成功后,如果是浏览器登录,一般会把Remember Me的Cookie写道客户端并保存。
  2. 关闭浏览器再次重新打开,会发现浏览器还是记住你。
  3. 访问一般的网页服务器,仍然知道你是谁,且能正常访问。
  4. 但是,如果我们访问电商平台,如果要查看我的订单或者进行支付,此事还需再次进行身份的认证。

5.2、代码实现

5.2.1、设置记住我

在配置类里的安全管理器方法里添加记住我功能

5.2.2、配置记住我管理器以及Cookie属性

// Cookie的属性设置
public SimpleCookie rememberCookie() {SimpleCookie cookie = new SimpleCookie("rememberMe");// 设置跨域
//  cookie.setDomain(domain);cookie.setPath("/");cookie.setHttpOnly(true);cookie.setMaxAge(30*24*60*60); // 30天return cookie;
}//创建CookieMaanger
public CookieRememberMeManager rememberMeManager() {CookieRememberMeManager manager  =new CookieRememberMeManager();manager.setCookie(rememberCookie());manager.setCipherKey("1234567890987654".getBytes());return manager;
}

5.2.3、添加用户过滤器

保证在登陆成功后,Shiro将登陆成功的用户信息放入到cookie中存储

5.2.4、改造Controller登录接口

// 2、 封装请求对象到Token对象 开启RememberUsernamePasswordToken token = new UsernamePasswordToken(name,password,rememberMe);

5.2.5、改造登陆页面

<div>记住我:<input type="checkbox" name="rememberMe" value="true"> </div>

六、用户登出

用户登陆之后,配套的操作有登出操作,直接通过Shiro过滤器即可以实现

6.1、代码实现

【过滤器】

@Beanpublic DefaultShiroFilterChainDefinition shiroFilterChainDefinition() {DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition();// 设置不认证可以访问的资源filter.addPathDefinition("/shiro/userLogin", "anon");filter.addPathDefinition("/shiro/login","anon");// 配置登出操作filter.addPathDefinition("/logout", "logout");// 设置需要进行登录认证才可以访问的拦截范围filter.addPathDefinition("/**", "authc");// 添加remember的用户filter.addPathDefinition("/**", "user");return filter;}

【登陆后的页面改造】

七、授权、角色认证

7.1、角色认证

用户登录后,需要验证是否具有指定角色权限,Shiro也提供了方便的工具进行判断,

这个工具就是Realm的doGetAuthenticationinfo方法进行判断,出发权限判断的有两种方式

  1. 在页面中通过shiro:xxxx属性判断
  2. 在接口中通过注解@Requiresxxxxx判断

7.1.1、后端接口服务注解

Shiro安全框架【SpringBoot版】相关推荐

  1. 01.基于Irises的springboot项目框架(简版)

    01.基于Irises的springboot项目框架(简版) 介绍 基于Irises搭建的springboot单体应用框架(简版),支持Mybatis-plus.sql分析与打印.swagger.kk ...

  2. springboot 2.x 整合 shiro 权限框架

    序 在实际项目中,经常需要用到角色权限区分,以此来为不同的角色赋予不同的权利,分配不同的任务.比如,普通用户只能浏览:会员可以浏览和评论:超级会员可以浏览.评论和看视频课等:实际应用场景很多.毫不夸张 ...

  3. SpringBoot集成Shiro安全框架

    SpringBoot集成Shiro安全框架 1.shiro的定义 2.SpringBoot集成shiro的步骤 3.完成的效果 1.shiro的定义 1.shiro的作用 认证.授权.加密.会话管理. ...

  4. Shiro安全框架【快速入门】就这一篇!

    Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...

  5. Shiro安全框架的使用

    Shiro安全框架 1.介绍 Shiro有三个核心的概念:Subject.SecurityManager和Realms. Subject(主体): subject本质上是当前正在执行的用户的特定于安全 ...

  6. java权限框架_Java高级工程师必备技术栈-由浅入深掌握Shiro权限框架

    权限系统在任何一个系统中都存在,随着分布式系统的大行其道,权限系统也趋向服务化,对于一个高级工程师来说,权限系统的设计是必不可少需要掌握的技术栈 Apache Shiro™是一个功能强大且易于使用的J ...

  7. Shiro 安全框架

    简介: Apache Shiro提供了认证.授权.加密和会话管理功能,将复杂的问题隐藏起来,提供清晰直观的API使开发者可以很轻松地开发自己的程序安全代码.并且在实现此目标时无须依赖第三方的框架.容器 ...

  8. SpringBoot2.x 整合 shiro 权限框架

    每天早上七点三十,准时推送干货 在实际项目中,经常需要用到角色权限区分,以此来为不同的角色赋予不同的权利,分配不同的任务.比如,普通用户只能浏览:会员可以浏览和评论:超级会员可以浏览.评论和看视频课等 ...

  9. “动吧“ - crud 练习 part7 - Shiro安全框架简介 - 58~60 - 、[扩展] - 动态菜单 - 60

    名词: ------------------------------------------- subject - 主体.起因 - (登录到==>登录成功后 , 全部的记录) principal ...

最新文章

  1. 机器学习笔试题精选(四)
  2. 关于流水帐表序列号生成时的并发操作问题
  3. IE提示“存储空间不足,无法完成此操作”的错误
  4. 就业技术书文件表格_Word格式:工程预结算工作流程图及工作表单,附20余表格...
  5. 成功解决没有tf.nn.rnn_cell属性
  6. python描述图片内容_深度学习实现图像中文描述
  7. Git 推送到远程仓库
  8. cartographer学习笔记--如何保存cartagrapher_ros建好的地图
  9. Java高级篇——深入浅出Java类加载机制
  10. 用android制作一个记事本app_用扁平化呈现一个天气APP
  11. bootstrap-干货小结
  12. Oracle10.2.0.1开始可以在线删除数据文件
  13. dbeaver 设置编码_DBeaver 一个神奇的数据库操作软件
  14. 杭电1091题c语言答案,杭电题目acm部分答案.doc
  15. 打地鼠java的实验报告_java实验报告18-“打地鼠”游戏程序设计.doc
  16. 电子废物回收的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 游戏开发人员推荐书单
  18. 静态URL和动态URL有什么区别呢?
  19. 南大计算机学院在职博士,南京大学双证在职博士
  20. php 模板编译类,一个简单的模板类--编译型的(simplet类增强后)

热门文章

  1. 经由过程MyEclipse生成Hibernate类文件和hbm.xml文件,或者annotation文件
  2. 【Shell秒懂系列】引用及转义(单引号/双引号/反斜杠/反引号)
  3. 带外管理小工具--IPMITOOL常用操作指令
  4. win10 完全卸载 小黑笔记本
  5. Redis实战之好友关注功能
  6. 开发im即时通讯如何用Netty实现心跳机制、断线重连机制
  7. IT研发技能表v3.1
  8. STM32初学自学体验,新手经验
  9. 数据分析-PART4--数据分析方法
  10. 英语被动句中动词后可以接形容词吗