IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot与Shiro整合———Shiro简介 -> 正文阅读

[Java知识库]SpringBoot与Shiro整合———Shiro简介

Shiro

Shiro介绍

一款主流的java安全框架 不依赖任何容器  
可以运行在javaSE 和java EE项目中,
主要作用对访问系统的用户进行身份认证(进行登录操作),
授权(拥有某些权限才可以进行访问某个模块),会话管理,加密操作。

Shiro 结构化 工程化 解决大型项目中的安全

Shiro 就是用来解决管理的系统化框架。

编写认证和授权规则

Anon 无需认证

Authc 必须认证

authcBasic 需要通过HTTPBasic认证

user 不一定通过认证 只要曾经被Shiro记录即可 比如 记住我

授权过滤器

Perms 必须拥有某个权限 才能访问

Role 必须拥有某个角色才能访问

Port 请求的端口必须是指定值才可以

Rest 请求必须基于Restful POST、PUT、GET、DELETE

Ssl 必须是安全的url请求 协议是https

Shiro核心组件

用户、角色、权限

会给角色赋予权限 给用户赋予角色

在这里插入图片描述

1. UsernamePasswordToken Shiro 用来封装用户登录信息 使用用户的登录信息来创建令牌Token。
2. SecurityManager Shiro的核心部分 负责安全认证和授权。
3. Suject Shiro的一个抽象概念 包含了用户信息
4. Realm 开发者自定义模块 根据项目的需求 验证和授权的逻辑 全部卸载Realm中
5. Authenticationinfo 用户的角色信息集合 认证时使用
6. Authorzationinfo 角色的权限信息 授权时使用
7. DefaultWebSecurityManager 安全管理器
开发者自定义的Realm、需要注入到DefaultWebSecurityManager 进行管理才可以生效
8. ShiroFilterFactoryBean 过滤器工厂 Shiro的基本运行机制是开发者定制规则 Shiro去执行,具体的执行操作就是由ShiroFilterFactoryBean创建的一个个Filter 对象来完成的

  • Shiro整体的运行流程

在这里插入图片描述

自定义Shrio过滤器
对这个url进行拦截,需要先进行认证 根据需求判断对应的角色和权限

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.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>SpringBoot_Shiro</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBoot_Shiro</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.5.3</version>
        </dependency>

        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

ShiroConfig 配置类


//  配置类

@Configuration
public class ShiroConfig {


    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean  factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);

        // 权限设置
        Map<String,String> map = new HashMap<>();
        map.put("/main","authc");
        map.put("/manage","perms[manage]");
        map.put("/administrator","roles[administrator]");
        //  通过这个map进行设置相对应的过滤器
        factoryBean.setFilterChainDefinitionMap(map);
        //  设置登录页面  发送这个请求 被视图解析器 捕获  跳转到login.html
        factoryBean.setLoginUrl("/login");
        //  设置未授权页面
        factoryBean.setUnauthorizedUrl("/unauth");
        return factoryBean;
    }



    @Bean
    public DefaultWebSecurityManager securityManager(@Qualifier("accountRealm") AccountRealm accountRealm){
          DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
          manager.setRealm(accountRealm);
          return manager;
    }



    @Bean
    public AccountRealm accountRealm(){
        return  new AccountRealm();
    }



    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

}

AccountController 控制类


@Controller
//@RestController
public class AccountController {

    @GetMapping("/{url}")
    public String redirect(@PathVariable("url") String url){
        return url;
    }


    @PostMapping("/login")
    public String login(String username , String password, Model model){
        //  subject一个抽象概念  包含了用户信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try {
            subject.login(token);
            return "index";
        }catch (UnknownAccountException e){
            e.printStackTrace();
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }

    @GetMapping("/unauth")
    @ResponseBody
    public String unauth(){
        return "未授权,无法访问";

    }
}

AccountRealm realm自定义类

//自定义Realm
public class AccountRealm extends AuthorizingRealm {



    @Autowired
    private AccountService accountService;
//     用户的角色权限信息集合  授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取当前用户的信息
        Subject subject = SecurityUtils.getSubject();
        Account account = (Account) subject.getPrincipal();

        //  设置角色
        Set<String>  roles = new HashSet<>();
        roles.add(account.getRole());
        SimpleAuthorizationInfo  info = new SimpleAuthorizationInfo(roles);

        //  设置权限
        info.addStringPermission(account.getPerms());

        return info;
    }


//     用户的角色信息集合  登录
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        Account account =  accountService.finByUseranme(token.getUsername());
        if(account != null){
            return  new SimpleAuthenticationInfo(account,account.getPassword(),getName());
        }
        return null;
    }
}

在这里插入图片描述

  • 客户端拿到密码和用户名自动封装到token中 然后根据对应的用户名 进行查询 如果结果为null 表示没有该用户
    跳出对密码的验证 Shiro会抛出 一个账户不存在

  • 如果用户名存在 则开始验证密码 其中包括正确的密码 account.getPassword() 在和token中的密码 进行对比
    在SimpleAuthenticationInfo这个方法总进行对比

客户端拿到密码和用户名自动封装到token中 然后根据对应的用户名 进行查询 如果结果为null 表示没有该用户 跳出对密码的验证 Shiro会抛出 一个账户不存在

如果用户名存在 则开始验证密码 其中包括正确的密码 account.getPassword() 在和token中的密码 进行对比 在SimpleAuthenticationInfo这个方法总进行对比

在这里插入图片描述

在这里插入图片描述

运行结果展示

罗三用户登录效果
在这里插入图片描述

王三用户登录效果

在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:09:53  更:2022-04-09 18:13:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:20:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码