• Shiro安全框架之权限认证(授权)


     第一讲、权限认证核心要素

    权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源。 在权限认证中,最核心的三个要素是:权限,角色和用户;

    Authorization has three core elements that we reference quite a bit in Shiro: permissions, roles, and users.

     权限permissions,即操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利; 角色,是权限的集合,一中角色可以包含多种权限; 用户,在 Shiro 中,代表访问系统的用户,即 Subject;

    第二讲、授权

    一、编程式授权Programmatic Authorization

        在pom添加junit依赖

     <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
    </dependency>

       新建common包 ShiroUtil.java用于封装shiro/HelloWorld.java

       将ini文件设置成参数configFile动态添加进来解析将用户名和密码也动态添加进来

      

     package com.guo.common;
    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;
    public class ShiroUtil {
              public static Subject login(String configFile,String userName,String password){
                       // 读取配置文件,初始化SecurityManager工厂
                       Factory<SecurityManager> factory=new IniSecurityManagerFactory(configFile);
                       // 获取securityManager实例
                       SecurityManager securityManager=factory.getInstance();
                       // 把securityManager实例绑定到SecurityUtils
                       SecurityUtils.setSecurityManager(securityManager);
                       // 得到当前执行的用户
                       Subject currentUser=SecurityUtils.getSubject();
                       // 创建token令牌,用户名/密码
                       UsernamePasswordToken token=new UsernamePasswordToken(userName, password);
                       try{
                                // 身份认证
                                currentUser.login(token);       
                                System.out.println("身份认证成功!");
                       }catch(AuthenticationException e){
                                e.printStackTrace();
                                System.out.println("身份认证失败!");
                       }
                       return currentUser;
              }
    }

    1、基于角色的访问控制 Role-Based Authorization

    (a)在resource/新建个shiro_role.in

    [users]
    Robin=123456,role1,role2
    Tom=123,role1  

    用名户Robin 密码123456 角色是role1 role2 表示权限

    (b)方法

    hasRole(String roleName) 判断是否有这个角色,返回值是布尔类型,只判断一个

    hasRoles(List<String> roleNames) 可以判断多个角色是否拥有,返回布尔型数组

    hasAllRoles(Collection<String> roleNames) 判断角色是否全部拥有,要全都有才返回true

    在shiro包下新建个单元测试junittestcase,RoleTest用于测试上述方法

    @Test
             public void testHasRole() {
                       Subject currentUser=ShiroUtil.login("classpath:shiro_role.ini", "Robin", "123456");
                       System.out.println(currentUser.hasRole("role1")?"有role1这个角色":"没有role1这个角色");
                       boolean []results=currentUser.hasRoles(Arrays.asList("role1","role2","role3"));
                       System.out.println(results[0]?"有role1角色":"没有role1角色");
                       System.out.println(results[1]?"有role2角色":"没有role2角色");
                       System.out.println(results[2]?"有role3角色":"没有role3角色");
                       System.out.println(currentUser.hasAllRoles(Arrays.asList("role1","role2"))?"有role1 role2角色":"没有role1 role2角色");
                     currentUser.logout(); // 退出当前用户
     
             }

    除上述三个方法外还有

    checkRole(String roleName) 检查是否拥有角色,没有的话抛出异常而不是返回布尔值false

    checkRoles(Collection<String> roleNames)

    checkRoles(String... roleNames)

       

    2 基于权限的访问控制

    (a)再新建个shiro_permission.ini

    [users]
    Robin=123456,role1,role2
    Tom=123,role1
    [roles]
    role1=user:select
    role2=user:add,user:update

    因为基于权限所以 添加角色权限,role1有查找权限,role2有添加 修改权限

    (b)方法

    isPermitted(Permission p)判断角色是否有权限,返回布尔类型

    isPermitted(List<Permission> perms)

    isPermittedAll(Collection<Permission> perms)

    因为Permission是接口,不能实例化,实例化需实例化它的实现类,太麻烦所以实际项目中不用,直接用下面这种形式,直接传字符串

    isPermitted(String perm)

    isPermitted(String... perms)

    isPermittedAll(String... perms)

    (c)再新建个单元测试PermissionTest

             @Test
             public void testIsPermitted() {
                       Subject currentUser=ShiroUtil.login("classpath:shiro_permission.ini", "Robin", "123456");
                       // Subject currentUser=ShiroUtil.login("classpath:shiro_permission.ini", "jack", "123");
                       System.out.println(currentUser.isPermitted("user:select")?"有user:select这个权限":"没有user:select这个权限");
                       System.out.println(currentUser.isPermitted("user:update")?"有user:update这个权限":"没有user:update这个权限");
                       boolean results[]=currentUser.isPermitted("user:select","user:update","user:delete");
                       System.out.println(results[0]?"有user:select这个权限":"没有user:select这个权限");
                       System.out.println(results[1]?"有user:update这个权限":"没有user:update这个权限");
                       System.out.println(results[2]?"有user:delete这个权限":"没有user:delete这个权限");
                       System.out.println(currentUser.isPermittedAll("user:select","user:update")?"有user:select,update这两个权限":"user:select,update这两个权限不全有");
                      
                       currentUser.logout(); // 退出当前用户
             }

    除上述三个方法外还有

    checkPermission(Permission p) 判断角色是否有权限,没有抛出异常

    checkPermission(String perm)

    checkPermissions(Collection<Permission> perms)

    checkPermissions(String... perms)

    二,注解式授权

    @RequiresAuthentication 要求当前 Subject 已经在当前的 session 中被验证通过才能被访问或调用。

    @RequiresGuest 要求当前的 Subject 是一个"guest",也就是说,他们必须是在之前的 session 中没有被验证或被记住才

    能被访问或调用。

    @RequiresPermissions("account:create") 要求当前的 Subject 被允许一个或多个权限,以便执行注解的方法。

    @RequiresRoles("administrator") 要求当前的 Subject 拥有所有指定的角色。如果他们没有,则该方法将不会被执行,而

    且 AuthorizationException 异常将会被抛出。

    @RequiresUser RequiresUser 注解需要当前的 Subject 是一个应用程序用户才能被注解的类/实例/方法访问或调用。一个“应

    用程序用户”被定义为一个拥有已知身份,或在当前 session 中由于通过验证被确认,或者在之前 session 中的'RememberMe'

    服务被记住

    三,Jsp 标签授权

    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

    Guest 标签:用户没有身份验证时显示相应信息,即游客访问信息;

    User 标签:用户已经身份验证/记住我登录后显示相应的信息;

    Authenticated 标签:用户已经身份验证通过,即 Subject.login 登录成功,不是记住我登录的。

    notAuthenticated 标签:用户没有身份验证通过,即没有调用 Subject.login 进行登录,包括记住我自动登录

    的也属于未进行身份验证。

    principal 标签 显示用户身份信息,默认调用 Subject.getPrincipal()获取,即 Primary Principal。

    hasRole 标签 如果当前 Subject 有角色将显示 body 体内容。

    lacksRole 标签 如果当前 Subject 没有角色将显示 body 体内容。

    hasAnyRoles 标签 如果当前 Subject 有任意一个角色(或的关系)将显示 body 体内容。

    hasPermission 标签 如果当前 Subject 有权限将显示 body 体内容。

    lacksPermission 标签 如果当前 Subject 没有权限将显示 body 体内容。

    第三讲、Permissions 对权限深入理解

    单个权限 query

    单个资源多个权限 user:query user:add   多值 user:query,add

    单个资源所有权限 user:query,add,update,delete user:*

    所有资源某个权限 *:view

    实例级别的权限控制

    单个实例的单个权限 printer:query:lp7200 printer:print:epsoncolor

    所有实例的单个权限 printer:print:*

    所有实例的所有权限 printer:*:*

    单个实例的所有权限 printer:*:lp7200

    单个实例的多个权限 printer:query,print:lp7200

    第四讲、授权流程

     

    本博客为博主的学习笔记,不作任何商业用途。
  • 相关阅读:
    执行shell脚本的四种方式(转)
    linux free命令详解(一)
    linux TOP命令各参数详解【转载】
    grep命令
    vim常用命令
    IntelliJ Idea注释模板--类注释、方法注释
    [Chrome]抓请求直接生成可执行代码
    记录Markdown工具Typora
    VSCODE 配置远程开发环境
    [Boost::Polygon]多边形相减得到新的多边形序列
  • 原文地址:https://www.cnblogs.com/guo7533/p/8745868.html
Copyright © 2020-2023  润新知