Apache Shiro

Apache Shiro是一个Java的安全(权限)框架.

Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSe环境,也可以用在JavaEE环境

Shiro可以完成,认证,授权,加密,会话管理,Web集成

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

 

里面有Shiro 在gitee的下载地址什么的,看不懂,1分钟就解决了

建议好好读一下:

三个核心组件:Subject, SecurityManager 和 Realms.

Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。

Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。

Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。

Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果系统默认的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。

记住:

Subject subject=SecurityUtils.getSubject();

得到subject对象

UsernamePasswordToken token=new UsernamePasswordToken(username,password);

为什么需要这个token对象的原因。因为login方法需要该对象

subject.login(token)

好了这样用户信息就提交给SecurityManager了

---------------------------------------------------------------------------------------------------------------------------------

这些都是核心代码.稍微有个印象

上面的是简写,详细点如下:

//准备提交给SecurityManager的对象,我们需要设置值交给SecurityManager

Subject curentUser=SecurityUtils.getSubject()

//通过当前用户拿到Session

Session session=curentUser.getSession();

session.setAttribute("someKey","aValue");

String value=(String)session.getAttribute("someKey");

if(value.equals("aValue")){

        log.info("登录成功")

}

//如果是没有认证的用户:

if(!curentUser.isAuthenticated()){

        UsernamePasswordToken token=new UsernamePasswordToken("admin","123456");

        token.setRememberMe(true);//设置记住我

        try{

                curentUser.login(token);//这个其实就是将用户信息提交给SecurityManager

        }catch(UnknowAccountException e){//未知的账户

                log.info("There is no user with username of"+token.getPrincipal());

        }catch(IncorrectCredentialsException e){//用户锁定比如5次密码不对

                log.info("Password for account "+token.getPrincipal()+"was incorrect");

        }catch(LockedAccountException e){

                log.info("xxxxxx");

        }catch(AuthenticationException e){//认证异常  上面都是子类异常

                log.info(",........")

        }

}

比如当前用户是什么角色

if(currentUser.hasRole("yyyy")){

        xxxxx

}else{

        log.info("xxxx");

}

 用户有什么权限

if(currentUser.isPermitted("xxxx")){

        xxxxxxxxxx

}

 登出

currentUser.logout()

 以上代码,都先混个眼熟.

下面正式开始SpringBoot集成Shiro

原先也写过:SpringBoot项目整合Shiro_fhrui的博客-CSDN博客_springboot项目整合shiro

当复习了.

其实Shiro文档里都有,学会看文档,但是我不会

 

开始创建项目

 

 

 引入Spirng web 

 还有Thymeleaf模板

 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.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hrui</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>

        <!--Shiro依赖-->
        <dependency>
            <groupId>org.apache.shiro</groupId>-->
            <artifactId>shiro-spring-boot-web-starter</artifactId>-->
            <version> 1.7.1</version>
        </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>
            </plugin>
        </plugins>
    </build>

</project>

上面的shiro依赖先注释一下,先测试下Thymeleaf好不好用

写个控制器测试Thymeleaf

整个首页 

 启动项目

 访问下

localhost:8080

 Thymeleaf测试成功

现在导入Shiro依赖,把刚才注释掉的Shiro拿来用

 启动报错

 首先,需要自定义一个Realm

写个配置类,放在启动类里也可以 

 写点测试环境需要的东西

控制器加两接口

 

加两个页面

 

 首页加两个跳转

 启动测试下

访问

 环境搭建好了

也都可以跳转

 接下来要做的就是让有些页面可以跳转,有些有条件跳转

 关于Shiro自定好的过滤连名称见官网

那如果我改成这样

那就是首页可以进,add和update  需要有认证才可以

试一下      localhost:8080 

访问首页可以

点击进入add或者update  不让访问 重定向到了login.jsp ,但我们没写所以找不到

 那么写一个再添加登录接口    配置里配置下

 

 

 测试

localhost:8080   点击add或者update

改用通配符也可以 

那么拦截是写好了

接下来做认证,就是用户账密传进来  

写个登录接口

 修改下登录页面将传过去的msg接收下

 启动服务器

访问localhost:8080/login  点击提交

看后台输出

 说明已经提交到认证方法,只不过我们在认证里啥也没做,返回了null

 接下来,就去认证里干点好玩的事

 

 重启下服务,访问

localhost:8080/login  输入amamaw   123456  点击提交

如果用户名错误,或者密码错误都会有相应报错其实,输入正确用户名和密码可以登录index.html

接着我们访问数据源,这里用Druid数据源   引入Druid(德鲁伊底层用的还是JDBC)  Mybatis mysql驱动   log4j   lombok   Druid配置没整好    

<dependency>
    <groupId>org.springframework.boot</groupId>
        注意这里没有data不检查数据库
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

创建application.yml配置数据源,算了Druid的配置太麻烦

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: 123456

#mybatis配置
mybatis:
  type-aliases-package: com.hrui.pojo
  mapper-locations: classpath:/mapper/*.xml

创建pojo

持久层

然后.xml配置文件

xml配置可以其他项目复制    或者mybatis官网入门_MyBatis中文网

业务层

数据库建表

 插入点数据

 测试下

 那么现在可以在认证的方法中将数据变成从数据库查询出来的数据

 测试下

访问 localhost:8080

 点击add  或者update  被拦截  跳到登录页面

 输入正确账密  允许登录且可以访问add  update  

下面讲下Shiro关于密码加密的问题

如果在用户注册时候,使用了加密方式比如说MD5

那么需要我们重写一个方法,Shiro会自动调用,

就是告诉Shiro我们是怎么对密码明文进行加密的

 比如我将数据库密码改一下  

该密码就是通过MD5 加密一次后生产的 

然后重写Shiro要掉用的加密方法     比如你是MD5  或者MD5加盐值 如果有盐值,在认证返回时调用4个参数的构造  或者其他加密方式

重新访问   localhost:8080    访问登录   root  123456  访问也是OK的 

认证基本差不多了,现在讲下授权

首先需要配置授权

访问

localhost:8080

 随便几点add 或者update  到登录页

 

访问update是OK的

但是访问add报错401   Unauthorized 就是未授权

 正常情况未授权会跳转到未授权页面,这里也写一下  

控制器

配置类里指定未授权路径

 

重新访问

 登录访问 add页面

看下后台

也就是说什么值权限,Shiro访问了授权方法,只不过授权里我们什么没写返回的是null 

既然设置了权限,现在需要将权限赋值给用户

那么进入授权的方法  

但是这样写的话,也就是说有登录用户都有该权限 

这样访问就ok了,但是存在的问题是所有用户都有了该权限

其实在认证方法return时候返回的第一个参数,已经可以通过授权方法参数得到

就是单一用户的传递

这里在pojo  User里加个权限字段    perms

数据库表里字段也加上

 

 也就是说数据库该用户需要有具体的权限

 当然 ,实际上角色权限实际和用户表是分开关联的

 将update权限也加上

这样登录对应用户账号,只能访问可以访问的页面,没有权限就会跳转到没有权限页面

 而现在更合理的需求解决是:只允许看到登录用户有权限看到的页面,

没有权限就不让他看到(原来是都可以看到,只是点进去显示没有权限)

引入Shiro整合Thymeleaf依赖

<!--Shiro整合Thymeleaf-->
<dependency>
    <groupId>com.github.theborakompanioni</groupId>
    <artifactId>thymeleaf-extras-shiro</artifactId>
    <version>2.1.0</version>
</dependency>

引入之后还需要配置

 index.html修改下

 这样其实访问    localhost:8080  add和update就都不显示了

我们先访问  localhost:8080/login   登录用户

登录root   只能看到  add

 或者index.html加个登录按钮

其实上面有个问题,就是登录后  访问首页  权限还有  时因为Session没有清除

我在授权方法里放个Session进去

 下面是我猜的,自己写个按钮试试,也不想验证了 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hrui0706

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

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

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

打赏作者

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

抵扣说明:

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

余额充值