JAVA安全框架之shiro

Shiro是什么

Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架 。Shiro 可以完 成: 认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松 地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。

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

 

为什么要用 Shiro 

  1. shrio开源自 2003 年,到目前为止框架格局发生了相当大的变化,因此今天仍然有很多系统在使用 Shiro。这与 Shiro 的特性密不可分。
  2. 易于使用:使用 Shiro 构建系统安全框架非常简单。
  3. 全面:Shiro 包含系统安全框架需要的功能,满足安全需求的“一站式服务”。
  4. 灵活:Shiro 可以在任何应用程序环境中工作。虽然它可以在 Web、EJB 和 IoC 环境中工作,但不需要依赖它们。Shiro 也没有强制要求任何规范,甚至没有很多依赖项。
  5. 强力支持 Web:Shiro 具有出色的 Web 应用程序支持,可以基于应用程序 URL 和
  6. Web 协议(例如 REST)创建灵活的安全策略,同时还提供一组 JSP 库来控制页面输出。
  7. 兼容性强:Shiro 的设计模式使其易于与其他框架和应用程序集成。Shiro 与
  8. Spring、Grails、Wicket、Tapestry、Mule、Apache Camel、Vaadin 等框架无缝集成。社区支持:Shiro 是 Apache 软件基金会的一个开源项目,有完备的社区支

  Shiro的优势

  1. Shiro 的配置和使用比较简单。
  2. Shiro 依赖性低,不需要任何框架和容器,可以独立运行.Spring Security 依赖 Spring 容器;
  3. shiro 不仅仅可以使用在 web 中,它可以工作在任何应用环境中。在集群会话时 Shiro最重要的一个好处或许就是它的会话是独立于容器的。

 基本功能

  • Authentication:身份验证也可以叫做登录,是验证用户对应的身份;
  • Authorization:授权,即权限验证,验证用户是否有需要的权限,也就是判断权限够不够格能不能操作
  • Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的
  • 所有 信息都在会话中;
  • Cryptography:加密,保护数据的安全性。可以设置加密方式如MD5加密
  • Web Support:Web 支持,可以非常容易的集成到 Web 环境
  • Caching:缓存,登录过一次之后就缓存 之后再去判断权限之类的直接拿缓存
  • Concurrency:Shiro 支持多线程应用的并发验证
  • Testing:提供测试支持;
  • Subject:在Shiro中所做的几乎所有事情都基于当前执行的用户,称为Subject。
  • Remember Me:内置“记住我”–Shiro API中的标准功能是在用户返回应用程序时记住他们。

 

案例

        环境准备 

                       添加依赖

我们需要先创建一个maven依赖,因为上面说了shiro是不依赖容器的,在导入依赖

    <dependencies>
<!--        shiro框架依赖-->
        <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>

                        INI文件 

 Shiro 获取权限相关信息可以通过数据库获取,也可以通过 ini 配置文件获取

[users]
name1=abc123
name2=nb666


name1就是账号 abc123就是密码 格式是账号=密码

                        创建启动类 

package com.project.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;

public class ShiroRun {

    public static void main(String[] args) {
        // 初始化获取SecurityManger
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 获取数据
        SecurityManager securityManager = factory.getInstance();
        // 使用工具类设置数据
        SecurityUtils.setSecurityManager(securityManager);
        // 获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        // 创建token对象 web应用用户名密码从页面传递  这里是从shiro.ini中获取的账号密码
        AuthenticationToken token = new UsernamePasswordToken("name1","abc123");
        // 完成登录
        try {
            // 此方法是进行登录
            subject.login(token);
            System.out.println("登录成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("登录失败");
        }
    }
}

这样子我们就算是创建好了。接下来点击运行即可 

 

 权限授权

        这里我们需要去在ini中给用户指定角色  name1=abc123,admin

// 完成登录
        try {
            // 此方法是进行登录
            subject.login(token);
            System.out.println("登录成功");

            // hasRole这个api是判断角色
            if (subject.hasRole("admin")){
                System.out.println("恭喜admin用户访问");
            }else {
                System.out.println("不是admin不允许访问");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("登录失败");
        }

        这里我们还需要给角色设置权限   

[roles]
admin=user:delete
            // 判断有没有权限
            if (subject.isPermitted("user:delete")){
                System.out.println("允许删除");
            }else {
                System.out.println("没有权限不允许删除");
            }

 因为我们给了权限那么肯定是运行删除的 运行一下看看:

 shiro加密

package com.project.shiro;

import org.apache.shiro.crypto.hash.Md5Hash;

public class ShiroMd5 {
    public static void main(String[] args) {
        // 明文 设置我们的密码
        String password = "abc123";
        // 加密
        Md5Hash md5Hash = new Md5Hash(password);
        System.out.println("MD5加密的密文=" + md5Hash);
        // 加盐加密
        Md5Hash md5Hash1 = new Md5Hash(password, "abc");
        System.out.println("MD5加盐加密的密文=" + md5Hash1);
        // 三层加密
        Md5Hash md5Hash2 = new Md5Hash(password, "abc", 3);
        System.out.println("MD5三层加密的密文=" + md5Hash2);
    }
}

 

因为我们日常写的密码肯定是需要通过加密传输的,但是因为有些用户设置密码过于简单那么我们可以给设置加密,如果觉得还不安全可以设置加盐加密,如果还是不满足,那么直接使用这个三层加密,让密码更安全更不会被窃取 

自定义登录认证

因为默认的登录认证是不带加密的,想要实现加密的话我们可以自己写一个Realm类,首先要设置自定义的话呢我们必须要继承AuthenticatingRealm然后在这个类中做自己需要的业务和认证条件。

package com.project.shiro;

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.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;


// 必须要继承AuthenticatingRealm   这里我们就模拟一下就行
public class MyRealm extends AuthenticatingRealm {
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws
            AuthenticationException {
        //1 获取身份信息
        String principal = authenticationToken.getPrincipal().toString();
        //2 获取凭证信息
        String password = new String((char[]) authenticationToken.getCredentials());
        System.out.println("认证用户信息:" + principal + "---" + password);
        //3 获取数据库中存储的用户信息
        if (principal.equals("name1")) {
            //3.1 设置三层加密之后的密码
            Md5Hash md5Hash2 = new Md5Hash(password, "abc", 3);
            //3.2 创建封装了校验逻辑的对象,将要比较的数据给该对象
            AuthenticationInfo info = new SimpleAuthenticationInfo(
                    // 身份信息
                    authenticationToken.getPrincipal(),
                    // 加密后的密码
                    pwdInfo,
                    // 加盐的方式
                    ByteSource.Util.bytes("abc"),
                    // 信息
                    authenticationToken.getPrincipal().toString());
            // 必须要返回
            return info;
        }
        // 如果不符合用户信息直接返回空
        return null;
    }
}

还需要去shiro.ini中添加代码 注意: myrealm=自己的Realm的绝对路径 ,还需要把密码改成加密的密码哟

[main]
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.project.shiro.MyRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$myrealm

 运行

 至此我们的案例也就结束了。shiro是一个让我们写项目上手更简单更容易上手的一个安全框架.让我们一起期待一下下一篇文章吧。

 

 

 

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱游玩的小零子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值