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

Posted 锅锅7533

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

第四讲、授权流程

 

 

以上是关于Shiro安全框架之权限认证(授权)的主要内容,如果未能解决你的问题,请参考以下文章

JAVAWEB开发之权限管理——shiro入门详解以及使用方法shiro认证与shiro授权

Shiro 安全框架详解二(概念+权限案例实现)

shiro安全框架-用户认证授权以及权限控制

SpringBoot实现基于shiro安全框架的,配合thymeleaf模板引擎的用户认证和授权

Shiro安全框架入门篇

shiro的 认证 与 授权