• Shiro安全框架


    项目需求

    1、⽹站任何⻚⾯都必须登录成功之后才能浏览,除了登录⻚⾯之外。

    2、登录成功之后,不同的⽤户有不同的权限。超级管理员、管理员和游客有着不同的操作权限

    市面上安全拦截的技术

    • Shiro
    • Spring Security
    • oauth2.0协议

    Shiro简介

    官网:https://shiro.apache.org/web.html

    Apache Shiro是Java的一个安全(权限)框架。
    Shiro可以非常容易的开发出足够好的应用,不仅可以用在JavaSE环境,也可以用在JavaEE环境。
    Shiro可以完成:认证、授权、加密、会话管理、与Web集成、缓存等。

    1、SecurityManager :厨师,是真正的业务操作者

    2、Subject:服务员,负责提供API接⼝给⽤户使⽤。

    3、SecurityUtils:餐厅,⽤来将厨师和服务员整合到⼀起,提供完整的服务。

    4、Realm:材料,数据(数据库的数据),⼀般跟SecurityManager 配置使⽤

    Shiro案例

    1.新建maven项目导入Shiro依赖

        <properties>
            <maven.compiler.source>8maven.compiler.source>
            <maven.compiler.target>8maven.compiler.target>
        properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.apache.shirogroupId>
                <artifactId>shiro-coreartifactId>
                <version>1.3.2version>
            dependency>
    
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.12version>
                <scope>testscope>
            dependency>
    
            <dependency>
    
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.24version>
            dependency>
    
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-jdbcartifactId>
                <version>5.1.6.RELEASEversion>
            dependency>
        dependencies>
    

    2.测试一:

    2.1在resource包下创建shiro配置文件

    shiro.ini

    [users]
    zhangsan=123456, admin, guest
    lisi=654321, guest
    [roles]
    admin=select, insert, delete, update
    guest=select
    

    2.2.Subject创建角色权限进行测试

    TestShiro.java

    package com;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Scanner;
    
    public class TestShiro {
    
        @Test
        public void test(){
            ///     创建IniSecurityManagerFactory,无参构造器会默认调用classpath下 shiro.ini文件
            IniSecurityManagerFactory factory = new IniSecurityManagerFactory();
    
            //      使用IniSecurityManagerFactory对象的getInstance()方法得到SecurityManager对象
            SecurityManager manager = factory.getInstance();
    
            //      使用SecurityUtils工具类的setSecurityManager()方法将SecurityManager对象存入
            SecurityUtils.setSecurityManager(manager);
    
            //      使用SecurityUtils工具类的getSubject()得到Subject对象
            //          subject,主体,可以使用一个“用户”, 也可以是一段程序代码或者爬虫
            Subject subject = SecurityUtils.getSubject();
    
            Scanner input = new Scanner(System.in);
    
    //        System.out.println("请输入账户:");
    //        String name = input.next();
            String name = "zhangsan";
    
    //        System.out.println("请输入密码:");
    //        String pass = input.next();
            String pass = "123456";
    
    
            //      使用用户输入的用户名和密码创建一个UsernamePasswordToken对象
            UsernamePasswordToken token = new UsernamePasswordToken(name, pass);
    
            try {
    
                //  使用Subject主体在指定的token之上进行登录
                subject.login(token);
            } catch (UnknownAccountException e) {
                e.printStackTrace();
            } catch (IncorrectCredentialsException e) {
                e.printStackTrace();
            } catch (AuthenticationException e) {
                e.printStackTrace();
            }
    
    
            //  Subject的isAuthenticated()方法用来判断一个用户是否是属于认证成功
            System.out.println(subject.isAuthenticated());
    
            if(subject.isAuthenticated()){
                System.out.println(subject.hasRole("admin"));
                System.out.println(subject.hasRole("guest"));
    
                Collection<String> c = new ArrayList<>();
    
                c.add("admin");
                c.add("guest");
                c.add("guest02");
    
                System.out.println(subject.hasAllRoles(c));
    
                subject.checkPermission("select");
                subject.checkPermission("insert");
                subject.checkPermission("update");
                subject.checkPermission("delete");
                subject.checkPermissions("select", "delete");
            }
        }
    }
    

    Shiro Subject简介说明

    Shiro详解

    Subject:是Shiro的认证授权组件
       提供当前用户信息(角色 授权),然后进行登录,退出,权限验证等
       我们常将一个Subject对象称之为一个用户
    

    什么是token

    token就是令牌,前后端进行鉴权的一种有效形式,比传统的 session 鉴权更加方便,简单来说:当用户首次登陆时,网站会给你一张“门卡”,以后你可以凭借门卡直接进入,而无需再次申请。但一段时间之后门卡实效,你需要再到前台充磁,这里的门卡就是 token

    session与token的区别
    3.测试二

    shiro02.ini

    [users]
    zhangsan=21218cca77804d2ba1922c33e0151105, admin, guest
    lisi=654321, guest
    [roles]
    admin=select, insert, delete, update
    guest=select
    
    String pass = "888888";
    //使用MD5加密对密码进行加密
    pass = new Md5Hash(pass).toString();
     System.out.println(pass);//21218cca77804d2ba1922c33e0151105
    

    4.测试三(验证数据库中的数据)

    shiro3.ini

    [main]
    ds=org.springframework.jdbc.datasource.DriverManagerDataSource
    ds.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
    ds.username=root
    ds.password=123456
    ds.driverClassName=com.mysql.cj.jdbc.Driver
    
    jr=org.apache.shiro.realm.jdbc.JdbcRealm
    jr.dataSource=$ds
    jr.authenticationQuery=select pass from users where name =?
    
    securityManager.realm=$jr
    

    进入源码查看,在JdbcRealm源码中可以看到已经准备好了固定的SQL语句如果自己的SQL按照同样规则编写,则在配置文件中可以省略

    DriverManagerDataSource d;
    
    JdbcRealm j;
    

    测试类

    package cqfedu;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.subject.Subject;
    import org.junit.Test;
    
    public class TestShiro03 {
    
        @Test
        public void testShiro(){
            IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro03.ini");
    
            SecurityManager securityManager = factory.getInstance();
    
            SecurityUtils.setSecurityManager(securityManager);
    
            Subject subject = SecurityUtils.getSubject();
    
            //验证数据库信息
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "88888");
    
            subject.login(token);
    
            System.out.println(subject.isAuthenticated());
        }
    }
    

    4.密码加密

    package com;
    
    import org.apache.shiro.codec.Base64;
    import org.apache.shiro.crypto.hash.Md5Hash;
    import org.junit.Test;
    
    import java.nio.charset.StandardCharsets;
    
    public class TestPassword {
    
        private String pass = "888888";
    
        @Test
        public void testBase64(){
            //Base64加密
            byte[] encode = Base64.encode(pass.getBytes(StandardCharsets.UTF_8));
    
            System.out.println(new String(encode));
    
            //解密
            byte[] decode = Base64.decode(encode);
    
            System.out.println(new String(decode));
        }
    
        @Test
        public void testMD5(){
            //MD5加密
    //        String s = new Md5Hash(pass).toString();
            //第二个参数是为密码加盐 第三个参数是加密的循环次数 通过加盐的操作提高破译密码难度
            String s = new Md5Hash(pass,"salt",3).toString();
    
            System.out.println(s);
        }
    }
    
  • 相关阅读:
    opengl glfw demo 下载,在windows vs2015中运行
    Web渗透测试流程
    on java8之多态
    SQL查询优化---子查询优化、排序分组优化、覆盖索引优化
    Bigemap是如何在生态林业科技行业去应用的
    深入理解开闭原则、里氏替换原则
    美团外卖优惠券小程序 美团优惠券微信小程序 自带流量主模式 带教程
    Lua使用方式介绍
    js 处理数组合并vs对象合并
    压缩包系列
  • 原文地址:https://blog.csdn.net/qq_48578877/article/details/127112388