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知识库 -> shiro实战案例 -> 正文阅读

[Java知识库]shiro实战案例

结构

在这里插入图片描述
在这里插入图片描述

概念介绍

  • Subject

    我们把用户或者程序称为主体(如用户,第三方服务,cron作业),主体去访问系统或者资源
    SecurityManager

    安全管理器,Subject的认证和授权都要在安全管理器下进行

  • Authenticator

    认证器,主要负责Subject的认证
    Realm

    数据域,Shiro和安全数据的连接器,好比jdbc连接数据库; 通过realm获取认证授权相关信息

  • Authorizer

    授权器,主要负责Subject的授权, 控制subject拥有的角色或者权限

  • Cryptography

加解密,Shiro的包含易于使用和理解的数据加解密方法,简化了很多复杂的api

  • Cache Manager

缓存管理器,比如认证或授权信息,通过缓存进行管理,提高性能

代码

  • 常用api


在这里插入图片描述
在这里插入图片描述

-项目结构
在这里插入图片描述

  • 配置 pom
<?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>3.0.0-M1</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>shiro_demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>shiro_demo</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
<!--			<scope>runtime</scope>-->
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.6</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>

</project>

  • QuickStartTest02
	package com.example.shiro_demo;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;

/*

单元测试执行顺序
@BeoreClass
 */
public class QuickStartTest02 {

    private SimpleAccountRealm accountRealm = new SimpleAccountRealm();
    private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

    @Before
    public void init(){
        //初始化数据源
        accountRealm.addAccount("lihw", "123");
        accountRealm.addAccount("chendan", "456");

        defaultSecurityManager.setRealm(accountRealm);
    }

    @Test
    public void testAuthentication(){
        SecurityUtils.setSecurityManager(defaultSecurityManager);

        // 当前的操作 主体
        Subject subject = SecurityUtils.getSubject();
        // 用户输入的用户名密码
        UsernamePasswordToken token = new UsernamePasswordToken("chendan", "456");

        subject.login(token);
        System.out.println("认证结果:"+ subject.isAuthenticated());
    }
}

  • QuickStartTest03
package com.example.shiro_demo;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Before;
import org.junit.Test;

/*

单元测试执行顺序
@BeoreClass
 */
public class QuickStartTest03 {

    private SimpleAccountRealm accountRealm = new SimpleAccountRealm();
    private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

    @Before
    public void init(){
        //初始化数据源
        accountRealm.addAccount("lihw", "123","root", "admin");
        accountRealm.addAccount("chendan", "456", "user");

        defaultSecurityManager.setRealm(accountRealm);
    }

    @Test
    public void testAuthentication(){
        SecurityUtils.setSecurityManager(defaultSecurityManager);

        // 当前的操作 主体
        Subject subject = SecurityUtils.getSubject();
        // 用户输入的用户名密码
        UsernamePasswordToken token = new UsernamePasswordToken("chendan", "456");

        subject.login(token);
        System.out.println("认证结果:"+ subject.isAuthenticated());

        System.out.println("是否有对应角色:"+ subject.hasRole("user"));

        System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());

        // 退出
        subject.logout();

        System.out.println("---------------退出之后---------------------");

        System.out.println("认证结果:"+ subject.isAuthenticated());

        System.out.println("是否有对应角色:"+ subject.hasRole("root"));

        System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
    }
}

  • QuickStartTesTxt
package com.example.shiro_demo;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Before;
import org.junit.Test;

/*

单元测试执行顺序
@BeoreClass
 */
public class QuickStartTesTxt {



    @Before

    @Test
    public void testAuthentication(){

        Factory<SecurityManager> factory =  new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();


        SecurityUtils.setSecurityManager(securityManager);

        // 当前的操作 主体
        Subject subject = SecurityUtils.getSubject();
        // 用户输入的用户名密码
        UsernamePasswordToken token = new UsernamePasswordToken("jack", "456");

        subject.login(token);
        System.out.println("认证结果:"+ subject.isAuthenticated());

        System.out.println("是否有对应角色:"+ subject.hasRole("user"));

        System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());

        System.out.println("是否有video:find权限:"+ subject.isPermitted("video:find"));

        // 退出
        subject.logout();

        System.out.println("---------------退出之后---------------------");

        System.out.println("认证结果:"+ subject.isAuthenticated());

        System.out.println("是否有对应角色:"+ subject.hasRole("root"));

        System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
    }
}

  • shiro.ini
# 格式 name=password,role1,role2,..roleN
[users]
# user 'root' with password 'secret' and the 'admin' role,
jack = 456, user

# user 'guest' with the password 'guest' and the 'guest' role
xdcalss = 123, root


# 格式 role=permission1,permission2...permissionN   也可以用通配符
# 下面配置user的权限为所有video:find,video:buy,如果需要配置video全部操作crud 则 user = video:*
[roles]
user = video:find,video:buy
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *

  • QuickStartTesCustomRealm
package com.example.shiro_demo;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Before;
import org.junit.Test;

/**
 * 自定义的 realm
 */
public class QuickStartTesCustomRealm {



    @Before

    @Test
    public void testAuthentication(){

        CustomRealm customRealm = new CustomRealm();
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

        defaultSecurityManager.setRealm(customRealm);


        SecurityUtils.setSecurityManager(defaultSecurityManager);

        // 当前的操作 主体
        Subject subject = SecurityUtils.getSubject();
        // 用户输入的用户名密码
        UsernamePasswordToken token = new UsernamePasswordToken("jack", "123");

        subject.login(token);
        System.out.println("认证结果:"+ subject.isAuthenticated());

        System.out.println("是否有对应角色:"+ subject.hasRole("user"));

        System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());

        System.out.println("是否有video:find权限:"+ subject.isPermitted("video:find"));

        // 退出
        subject.logout();

        System.out.println("---------------退出之后---------------------");

        System.out.println("认证结果:"+ subject.isAuthenticated());

        System.out.println("是否有对应角色:"+ subject.hasRole("root"));

        System.out.println("getPrincipal 认证结果:"+ subject.getPrincipal());
    }
}

  • CustomRealm
package com.example.shiro_demo;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class CustomRealm extends AuthorizingRealm {

    private final Map<String, String>  userInfoMap = new HashMap<>();
    {
        userInfoMap.put("jack", "123");
        userInfoMap.put("lhw", "456");
    }

    private final Map<String, Set<String>>  permissionMap = new HashMap<>();
    {
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        set1.add("video:find");
        set1.add("video:buy");

        set2.add("video:add");
        set2.add("video:delete");

        permissionMap.put("jack", set1);
        permissionMap.put("lihw", set2);
    }

    private final Map<String, Set<String>>  roleMap = new HashMap<>();
    {
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        set1.add("role1");
        set1.add("role2");

        set2.add("root");


        roleMap.put("jack", set1);
        roleMap.put("lihw", set2);
    }



    /**
     * 进行权限校验的时候会调用
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权认证 doGetAuthorizationInfo");

        String name = (String) principalCollection.getPrimaryPrincipal();
        // 正常要从数据查找用户权限
        Set<String> permissions = getPermisstionsByNameFromDb(name);
        Set<String> roles = getRoleByNameFromDb(name);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);


        return simpleAuthorizationInfo;
    }

    private Set<String> getRoleByNameFromDb(String name) {

        return roleMap.get(name);
    }

    private Set<String> getPermisstionsByNameFromDb(String name) {

        return permissionMap.get(name);
    }


    /**
     * 用户登录的时候会调用
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("登录认证 doGetAuthenticationInfo");
        //获取用户名
        String name = (String) authenticationToken.getPrincipal();
        String pwd = userInfoMap.get(name); // 模拟从数据库拿密码

        if(pwd == null || "".equals(pwd)) {
            return null;
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, this.getName());
        return simpleAuthenticationInfo;
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:14:58  更:2022-03-08 22:15:24 
 
开发: 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 11:35:56-

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