Shiro权限框架 01(shiro框架入门)

目录

一、Shiro简介

1.1、什么是shiro? 

        1.2、 在应用程序角度来观察如何使用Shiro完成工作?

1.3、Shiro架构

shiro功能简介:

Shiro核心架构图:

二、Shiro入门案例

准备工作:

1、导入相关依赖

2、编写shiro.ini文件(Shiro框架的配置文件)

 3、使用Shiro

4、Shiro与Web容器集成

        ①在web.xml中进行shiro过滤器配置

        ②添加配置文件 shiro-web.ini


一、Shiro简介

1.1、什么是shiro? 

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现  用户认证用户授权

 ​ 权限管理,一般指根据系统设置的安全策略或者安全规则,用户可以访问而且只能访问自己被授权的资源,不多不少。权限管理几乎出现在任何系统里面,只要有用户和密码的系统。

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

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

1.2、 在应用程序角度来观察如何使用Shiro完成工作?

Subject主体;代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,例如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者。

SecurityManager安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器。

Realm;Shiro从Realm获取安全数据(例如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

如图所示:

Shiro权限框架 01(shiro框架入门)_第1张图片

1.3、Shiro架构

① subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。

securityManager:安全管理器,主体进行认证和授权都是通过securityManager进行。securityManager是一个集合,  真正做事的不是securityManager而是它里面的东西。

authenticator:认证器,主体进行认证最终通过authenticator进行的。

authorizer:授权器,主体进行授权最终通过authorizer进行的。

sessionManager:web应用中一般是用web容器(中间件tomcat)对session进行管理,shiro也提供一套session管理的方式,shiro不仅仅可以用于web管理也可以用于cs管理,所以他不用web容器的session管理。

  ⑥SessionDao:  通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。(如果用tomcat管理session就不用SessionDao,如果要分布式的统一管理session就要用到SessionDao)。

cache Manager:缓存管理器,主要对session和授权数据进行缓存(权限管理框架主要就是对认证和授权进行管理,session是在服务器缓存中的),比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理(redis是缓存框架)。

  ⑧ realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据(原来是通过数据库取的)。 注意:authenticator认证器和authorizer授权器调用realm中存储授权和认证的数据和逻辑。

  ⑨ cryptography:密码管理,比如md5加密,提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。比如 md5散列算法(md5只有加密没有解密)。

shiro功能简介:

 Shiro权限框架 01(shiro框架入门)_第2张图片

 

**Authentication:**身份认证/登录,验证用户是不是拥有相应的身份;

**Authorization:**授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

Session Manager:会话管理**,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;**会话可以是普通 JavaSE环境,也可以是 Web 环境;

Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

Web Support:Web 支持,可以非常容易的集成到Web 环境;

Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

Testing:提供测试支持;

Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了

Shiro核心架构图:

Shiro权限框架 01(shiro框架入门)_第3张图片  

知识总结:

1、认证        ——>接管了用户登录操作

2、授权        ——>接管理系统资源的分配

3、会话管理        ——>接管了Tomcat中国的session

4、缓存管理        ——>主要提示权限管理的执行效率

5、密码管理        ——>对密码进行加密

二、Shiro入门案例

准备工作:

1、导入相关依赖

导入pom依赖,将以下代码替换pom.xml中的 


        UTF-8
        1.7
        1.7
        3.7.0

        
        4.12
        4.0.0
        2.9.1
        1.7.7
        3.2.0

        1.2.5
    

    
        
        
            org.apache.shiro
            shiro-core
            ${shiro.version}
        
        
        
            org.apache.shiro
            shiro-web
            ${shiro.version}
        
        
        
            junit
            junit
            ${junit.version}
            test
        
        
        
            javax.servlet
            javax.servlet-api
            ${servlet.version}
            provided
        
        
        
            org.slf4j
            slf4j-api
            ${slf4j.version}
        
        
            org.slf4j
            jcl-over-slf4j
            ${slf4j.version}
            runtime
            
                
                    slf4j-api
                    org.slf4j
                
            
        
        
        
            org.apache.logging.log4j
            log4j-slf4j-impl
            ${log4j2.version}
            
                
                    slf4j-api
                    org.slf4j
                
            
        
        
        
            org.apache.logging.log4j
            log4j-api
            ${log4j2.version}
        
        
            org.apache.logging.log4j
            log4j-core
            ${log4j2.version}
        
        
        
            org.apache.logging.log4j
            log4j-web
            ${log4j2.version}
            runtime
        
        
        
            com.lmax
            disruptor
            ${log4j2.disruptor.version}
        

    

 将以下代码直接导入pom.xml中

 
            
            
                src/main/java
                
                    **/*.xml
                
            
            
            
                src/main/resources
                
                    *.properties
                    *.xml
                    *.ini
                
            
        

将以下代码直接导入pom.xml中(maven编译器) 


                    org.apache.maven.plugins
                    maven-compiler-plugin
                    ${maven.compiler.plugin.version}
                    
                        ${maven.compiler.source}
                        ${maven.compiler.target}
                        ${project.build.sourceEncoding}
                    
                

  

log4j2.xml 





    
        
        
        ${sys:user.home}/logs
        ${sys:user.home}/logs/error
        ${sys:user.home}/logs/warn

        
        
        
        
        

        
        %d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n
        
    

    
        
        
            
            
            
            
            
        

        
        
        
            
        
        
        
            
            
            
            
                
                
                
                
                
                
            
        

        
            
            
            
                
                
            
            
            
        

        
            
            
            
                
                
                
            
        

    

    
    
        
        
        
        
        
        
        
        


        
        
            
            
            
            
        
    


 

2、编写shiro.ini文件(Shiro框架的配置文件)

shiro.ini

代码展示:

[users]
zs=123
ls=456
ww=789

Shiro权限框架 01(shiro框架入门)_第4张图片

 3、使用Shiro

  1. 读取ini数据源文件,得到securitymanager工厂
  2. 获取securitymanager实例
  3. 将securitymanager交给Securityutils进行管理
  4. 通过securityutil获取登入用户主体subject
  5. 创建登入令牌token
  6. 利用主体subject进行登入
  7. 退出也使用subject

解析:

Shiro权限框架 01(shiro框架入门)_第5张图片

 代码块展示:

package com.chenchen.demo;

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;

/**
 * @author chenchen
 * @site www.javacc.com
 * @company xxx公司
 * @create  2022-08-24 21:47
 */
public class Demo1 {
    public static void main(String[] args) {
//        将数据源放入工厂对像(将数据源放入工厂对象中)
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//        获取事务管理器(安全管理器)的实例
        SecurityManager instance = factory.getInstance();
//        将事务管理器实例交给SecurityUtils进行管理
        SecurityUtils.setSecurityManager(instance);
//        从安全管理器工具包中拿到登录的主体(用户)
        Subject subject = SecurityUtils.getSubject();
//      生成token 令牌 设置密码
        UsernamePasswordToken token = new UsernamePasswordToken("zs", "123");
//      这个时候这个用户是否可以登录取决于有没有token令牌--->登录密码
//      主体携带令牌进行登录
        subject.login(token);
        System.out.println("登录成功....");
        subject.logout();
        System.out.println("登出成功....");

    }
}

效果展示:

Shiro权限框架 01(shiro框架入门)_第6张图片

4、Shiro与Web容器集成

回顾:

        Spring与Web容器集成,配置了监听器ContextLodaListener

        Springmvc与Web容器集成,配置了Dispatcherservlet

Shiro与Web集成:

        ①在web.xml中进行shiro过滤器配置

【这里的过滤器就是加载数据源,在你启动的时候拦截了所有的请求,将前面的那六步在过滤器中完成(使用shiro的六步骤)】

 Shiro权限框架 01(shiro框架入门)_第7张图片

 web.xml代码块展示:



  Archetype Created Web Application

  
  
    shiroConfigLocations
    classpath:shiro-web.ini
  
  
    org.apache.shiro.web.env.EnvironmentLoaderListener
  

  
  
    ShiroFilter
    org.apache.shiro.web.servlet.ShiroFilter
  
  
    ShiroFilter
    /*
  


        ②添加配置文件 shiro-web.ini

【辅助shiro过滤器完成shiro的六步骤,而前面我们所用的配置文件是shiro.ini的原因是因为我们没有使用web容器】

Shiro权限框架 01(shiro框架入门)_第8张图片 shiro-web.ini        代码块展示:

[main]
#定义身份认证失败后的请求url映射,loginUrl是身份认证过滤器中的一个属性
authc.loginUrl=/login
#定义角色认证失败后的请求url映射,unauthorizedUrl是角色认证过滤器中的一个属性
roles.unauthorizedUrl=/unauthorized.jsp
#定义权限认证失败后请求url映射,unauthorizedUrl是角色认证过滤器中的一个属性
perms.unauthorizedUrl=/unauthorized.jsp

[users]
zs=123,role1
ls=123,role2
ww=123,role3
zdm=123,admin


[roles]
role1=user:create
role2=user:create,user:update
role3=user:create,user:update,user:delete,user:view,user:load
admin=user:*



#定义请求的地址需要做什么验证
[urls]
#请求login的时候不需要权限,游客身份即可(anon)
/login.do=anon

#请求/user/updatePwd.jsp的时候,需要身份认证(authc)
/user/updatePwd.jsp=authc

#请求/admin的时候,需要角色认证,必须是拥有admin角色的用户才行
/admin/*.jsp=roles[admin]

#请求/teacher的时候,需要权限认证,必须是拥有user:create权限的角色的用户才行
/user/teacher.jsp=perms["user:update"]

 三、测试

添加测试所需要的代码:

Shiro权限框架 01(shiro框架入门)_第9张图片

 addUser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

用户新增

listUser.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

用户查询(所有)

resetPwd.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

重置用户密码

updateUser.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

用户修改

teacher.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

老师个人信息

updatePwd.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

个人密码修改

index.jsp 



Hello World!

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

用户登陆

${message}
帐号:
密码:

main.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="r" uri="http://shiro.apache.org/tags" %>


    Title


主界面<%=System.currentTimeMillis()%>,欢迎您:[${sessionScope.username}]

unauthorized.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    

未授权的操作

未授权的操作,请与管理员联系,或切换帐号重新登陆后再试!

Ok,那么我们现在可以开始测试了,

Shiro权限框架 01(shiro框架入门)_第10张图片

Shiro权限框架 01(shiro框架入门)_第11张图片 

Shiro权限框架 01(shiro框架入门)_第12张图片 点击运行,效果如下:

Shiro权限框架 01(shiro框架入门)_第13张图片

 这个时候,如果我们想要跳到其他页面的时候是不可以的,因为需要身份验证,

Shiro权限框架 01(shiro框架入门)_第14张图片所以这时候,需要写身份验证测试,

 Shiro权限框架 01(shiro框架入门)_第15张图片

 LoginServlet.java        代码展示:

package com.chenchen.demo;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author chenchen
 * @site www.javacc.com
 * @company xxx公司
 * @create  2022-08-25 14:50
 *
 * 用于用户登录
 */

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取用户账号
        String username = req.getParameter("username");
//        获取用户密码
        String password = req.getParameter("password");
//        拿到令牌
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//        从安全管理器工具包中拿到登录的主体(用户)
        Subject subject = SecurityUtils.getSubject();
//        进行判断
        try{
//            匹配则转发进入主界面
            subject.login(token);
            req.getRequestDispatcher("/main.jsp").forward(req,resp);
        }catch (Exception e){
//            反之则进入登录界面
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
//            提示
            req.setAttribute("message","用户密码输入有误!!!");
        }

    }
}

 同样的还需要退出登录,

logout.java        代码展示:

package com.chenchen.demo;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author chenchen
 * @site www.javacc.com
 * @company xxx公司
 * @create  2022-08-25 14:50
 *
 * 用于用户登录
 */

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取用户账号
        String username = req.getParameter("username");
//        获取用户密码
        String password = req.getParameter("password");
//        拿到令牌
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//        从安全管理器工具包中拿到登录的主体(用户)
        Subject subject = SecurityUtils.getSubject();
//        进行判断
        try{
//            匹配则转发进入主界面
            subject.login(token);
            req.getRequestDispatcher("/main.jsp").forward(req,resp);
        }catch (Exception e){
//            反之则进入登录界面
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
//            提示
            req.setAttribute("message","用户密码输入有误!!!");
        }

    }
}

运行效果展示:

Shiro权限框架 01(shiro框架入门)_第16张图片

 当我们身份验证成功之后进入主界面(main.jsp)

Shiro权限框架 01(shiro框架入门)_第17张图片

 我们的shiro框架是一款权限管理框架,对于不同的用户可进行权限划分

Shiro权限框架 01(shiro框架入门)_第18张图片

 

 例如我们使用用户:zs进入

Shiro权限框架 01(shiro框架入门)_第19张图片

 OK,以上就是今天的分享内容,希望本期内容能帮助到您~~

我们下期再见!

                                                        预告下期内容:Shiro认证。

你可能感兴趣的:(spring,mybatis,java,idea)