Shiro框架入门到熟悉(持续更新中)

Shiro框架之新手入门----持续更新中(有案例说明)

如有侵权请联系博主,并进行删除

Shiro简介

hiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证、用户授权。

spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。

shiro不依赖于spring,shiro不仅可以实现 web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量框架,越来越多企业项目开始使用shiro。

使用shiro实现系统的权限管理,有效提高开发效率,从而降低开发成本。

Shiro运行原理图

在这里插入图片描述

模块介绍(图片转载地址:https://img-blog.csdn.net/20161220192235255?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUVE5OTQ0MDYwMzA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

在这里插入图片描述

Subject:主体,代表了当前操作“用户”,用户不一定指人,也可以是程序,,所有的Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager,主体要访问系统,系统需要对主体进行认证、授权。

SecurityManager:安全管理器,可以理解为springmvc里面的DispatcherServlet前端控制器,主体进行认证和授权都是通过securityManager进行。

Realm:域,安全数据源。Shiro从Realm获取数据,相当于SecurityManager需要验证身份,那么他需要从Realm获取相应的用户进行比较确定用户身份是否合法,可以把Realm理解为DataSource

认证过程(转载与:https://blog.csdn.net/mine_song/article/details/61616259?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160315732219724835862833%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160315732219724835862833&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-1-61616259.pc_search_result_cache&utm_term=shiro%E6%A1%86%E6%9E%B6%E5%8E%9F%E7%90%86%E8%AE%A4%E8%AF%81%E6%B5%81%E7%A8%8B&spm=1018.2118.3001.4187)

在这里插入图片描述

解析
1、通过ini配置文件创建securityManager

2、调用subject.login方法主体提交认证,提交的token

3、securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。

4、ModularRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息

5、IniRealm根据输入的token(UsernamePasswordToken)从 shiro.ini查询用户信息,根据账号查询用户信息(账号和密码)

     如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)

     如果查询不到,就给ModularRealmAuthenticator返回null

6、ModularRealmAuthenticator接收IniRealm返回Authentication认证信息

     如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)

     如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)
     和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)
授权流程

在这里插入图片描述

解析

1、对subject进行授权,调用方法isPermitted(“permission串”)

2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

3、ModularRealmAuthorizer执行realm(自定义的Realm)从数据库查询权限数据

调用realm的授权方法:doGetAuthorizationInfo

4、realm从数据库查询权限数据,返回ModularRealmAuthorizer

5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对

6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。

接下来为大家进行代码解析

首先按照下图进行项目结构搭建(由于简单就不一步一步教了)

在这里插入图片描述

接下来我会我把每个文件中对应的代码写给大家,没有写的就是默认的

1.Shiro.in的配置(有注解很好理解,不懂留言)

[users]
root=123456,admin
test=000000,test

[roles]
admin=*
test=search,add,update

以下是配置详解图
在这里插入图片描述

2.ShiroTest类的代码

package com.shiro.test.javase;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
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.apache.shiro.util.Factory;

/*
boolean[] isPermitted(String var1):可以查看多个权限,并且可以按照顺序把每一个权限的校验结果封装到布尔类型数组里面
boolean[] isPermittedAll(String var1):判断同时是否具有多个权限
 */
public class ShiroTest {
    public static void main(String[] args) {
        //指定读取的配置文件
        Factory<SecurityManager> factory =
        new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        //将SecurityManager绑定到上下文当中,全局设置只需要设置一次
        SecurityUtils.setSecurityManager(securityManager);
        //subject与当前系统交互的对象
        Subject subject = SecurityUtils.getSubject();
        //如果把用户改为root,那么所有的权限都可以用,因为把他设置了为了最高权限
        UsernamePasswordToken token = new UsernamePasswordToken("test","000000");
        //代表用户是否验证过

        try {
            subject.login(token);
            //如果判断成功
            if(subject.isAuthenticated()){
                System.out.println("登录成功");
                //判断角色用hasRole
                if(subject.hasRole("admin")){
                    System.out.println("有admin角色");

                }else{
                    System.out.println("没有admin角色");
                }
                //isPermitted用来判断用户权限
                if(subject.isPermitted("search")){
                    System.out.println("有search权限");
                }else {
                    System.out.println("没有search权限");
                }
                if(subject.isPermitted("del")){
                    System.out.println("有del权限");
                }else {
                    System.out.println("没有del权限");
                }
                //boolean[] isPermittedAll(String var1):判断同时是否具有多个权限
                if(subject.isPermittedAll("add","update")){
                    System.out.println("有\"add\",\"update\"权限");
                }else {
                    System.out.println("没有\"add\",\"update\"权限");
                }
            }
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.println("用户名或密码错误,登录失败");
        }
    }
}

身份验证认证流程(之前的只是一个小入门案列)

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

流程解析:

1.首先调用Subject.login(token)进行登录,其会自动委托给SecurityManager,调用之前必须通过SecurityUtils.setSecurityManager();进行设置

2.SecurityManager负责真正的身份逻辑验证,他会委托给Authenticator进行身份验证

3.Authenticator才是真正的身份验证者,ShiroAPI中核心的身份认证入口点,此处可以自定义插入自己的实现

4.Authenticator看你会委托给相应的AuthenticationStrategy进行多Realm身份验证,默认ModulRealmAuthenticator会调用AuthenticationStreategy进行多身份验证

5.Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有会/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

接下来给大家截图搞一下小补充

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

另一种方式实现安全登录注册,只需要

1.首先自己做一个加密算法,代码如下所示

/*
工具类用来加密
 */
public class PasswordUtil {
    public static String md5(String source, Object salt) {
        //散列次数
        int hashIterations = 1024;
        SimpleHash simpleHash = new SimpleHash("md5", source,salt,hashIterations);
        String md5 = simpleHash.toString();
        return md5;
    }

2.写一个controller类,进行判断

 @Autowired
    private Service service;
    @ResponseBody
    @RequestMapping("/doLogin")
    public String diLogin(String username,String password,boolean rememberMe){

        User1 all = service.findAll(username);
        //if(all==null) throw new UnknownAccountException("zhanghaobucunzai");
        if(all==null) {
            return "zhanghaobucunzai";
        }
        String salt = all.getSalt();
        String s = PasswordUtil.md5(password, salt);
        System.out.println(s);


        if(all.getPassword().equals(s)){
            System.out.println(all.getPassword());
            System.out.println("登录成功");
            return "dlcg";
        }else
            System.out.println("登录失败");
        return "dlsb";}

3.接下来还有前端页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>AdminLTE 2 | Log in</title>
    <title>Title</title>
    <link href="http://apps.bdimg.com/libs/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
    <!--font-awesome 核心我CSS 文件-->
    <link href="//cdn.bootcss.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
    <!-- 在bootstrap.min.js 之前引入 -->
    <script src="http://apps.bdimg.com/libs/jquery/2.0.0/jquery.min.js"></script>
    <!-- Bootstrap 核心 JavaScript 文件 -->
    <script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>

    <![endif]-->

    <!-- Google Font -->
</head>

<body class="hold-transition login-page">
<div style="width: 400px ;align-content: center;text-align: center">
    <div class="login-box">
        <div class="login-logo">
            <a href="#"><b>DB-</b>SYS</a>
        </div>
        <!-- /.login-logo -->
        <div class="login-box-body">
            <p class="login-box-msg">Sign in to start your session</p>
            <div  v-show="error.msg" class="alert-danger alert-dismissible">123</div>
            <form method="post">
                <div class="form-group has-feedback">
                    <input type="text" id="usernameId" name="username" class="form-control" placeholder="username">
                    <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
                </div>
                <div class="form-group has-feedback">
                    <input type="password" id="passwordId" name="password" class="form-control" placeholder="Password">
                    <span class="glyphicon glyphicon-lock form-control-feedback"></span>
                </div>

                <div class="rem-for-agile">
                    <input type="checkbox" name="rememberMe" class="remember" value="true">rememberMe<br>
                    <!-- <a href="#">忘记密码</a><br> -->
                </div>


               <%-- <div class="row">
                    <div class="col-xs-8">
                        <div class="checkbox icheck">
                            <label>
                                <input type="checkbox" id="rememberId" value="true"> Remember Me
                            </label>
                        </div>
                    </div>--%>
                    <!-- /.col -->
                    <div class="col-xs-4">
                        <button type="button"  class="btn btn-primary btn-block btn-flat btn-login" id="login-a">sing in</button>
                    </div>
                    <!-- /.col -->
                </div>
            </form>

        </div>
        <!-- /.login-box-body -->
    </div>
    <!-- /.login-box -->
</div>
<script type="text/javascript">
    $("#login-a").click(function () {
        var val = $("#usernameId").val();
        var val1 = $("#passwordId").val();
        var val2 = $("#rememberId").val();
        $.ajax({
            charset: "utf-8",
            type: "post",
            url: "user/doLogin",
            dataType: "text",
            data: {
                'username': val,
                'password': val1,
                'rememberId': val2,
            },
             success: function (data) {
                 alert(data);
                 top.location.reload();
             }
        })
    })

</script>
</body>
</html>

4.补充:接口类

package com.launch.service;

import com.launch.entity.User1;

import java.util.List;

public interface Service {
    public User1 findAll(String username);
    //public void save(User1 user1);
}

封装类

package com.launch.entity;

public class User1 {
    private Integer id;
    private String username;
    private String password;
    private String salt;

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User1{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                '}';
    }
}

以上就是不用shiro实现登录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像的目标属于哪个类别。 定位问题:确定目标在图像的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值