【Shiro】Permission字符串及认证授权的相关内容

一、Permission字符串

1、格式

资源:权限:操作
(常用格式是:模块:功能:操作

  1. 资源 :指系统中需要被保护的对象、数据或服务等。资源可以是一个统称,也可以是具体的对象。
  2. 权限 :指对资源所具备的操作功能,用于限制对资源的访问和使用。权限可以是一个动词或描述性词语。需要准确表示权限的作用或功能。
  3. 操作:指执行某个权限对应的具体行为,如CRUD。

通配符(*)表示一个或多个。

还可以使用简单的通配符,如 sys:user:*,建议省略为 sys:user(分离前端不能使用星号写法)
举例1 sys:user 将于 sys:usersys:user: 开头的所有权限字符串匹配成功
举例2 sys 将于 syssys: 开头的所有权限字符串匹配成功

2、具体示例

模块:功能:操作
例1:sys:user:edit 代表 系统模块:用户功能:编辑操作
例2:report:couponReceive:* 代表 报表模块:优惠券领取功能:所有操作

3、其他分隔符

  1. 使用"/"作为分隔符
    一种层次结构路径,显示权限是如何在资源之间划分的。
    例如,posts/view/read

  2. 使用"."作为分隔符
    通常适用于具有明确定义的对象或资源层次结构的系统,使权限更像分层组件或命名空间。
    例如,posts.view.read

疑惑:上面3种形式(:/.),在实际开发中应该用那种分隔符?
回答:个人理解,用那种都行,主要根据系统最开始时怎么定义,想用那种都行。

二、认证授权的相关内容

1、权限与URI,以及URL的区别

  • 权限(permission):在 其他分隔符 中,有用"/"作为分割符,与URL和URI的样式很相似,但它主要还是作为权限的字符串。
  • URI:唯一标识一个资源。filterChainDefinitionMap中,URI既可以是后端请求的地址,也可以是静态资源的路径

URI通配符:
1. ? :匹配一个字符。【任意的一个字符】
2. * :匹配零个或多个字符串。【任意的一个路径】
3. ** :匹配路径中的零个或多个路径。【任意路径及子路径】

注意:

上面写的是URI(统一资源标识符),不是URL(统一资源定位符),两者存在区别:
URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI 是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。

简单说:
URI:身份证号 (只能知道有这么个人,但具是谁不知道)
URL:身份证住址+姓名 (不仅具体知道这个人是谁,还能找到他)
只要能唯一表示资源的就是URI,在URI的基础上给出其资源的访问方式的就是URL。
以上参考:
URI和URL的区别与联系

在实际开发中,权限(permission)和URI是结合使用的。

@Bean
public FilterChainDefinitionMap createFilterChainDefinitionMap() {
    
    
    Map<String, String> filterChainMap = new LinkedHashMap<>();
    filterChainMap.put("/public/**", "anon");
    filterChainMap.put("/admin/**", "authc,roles[admin]");
    filterChainMap.put("/**", "authc");
    return new DefaultFilterChainDefinitionMap(filterChainMap);
}

在上面的例子中,我们将 /public/** 路径下的 URI 设置为不需要认证即可访问(anon),
/admin/** 路径下的 URI 设置为 需要认证 和拥有 admin 权限才能访问(authc,roles[admin]),
将其他所有路径下的 URI 设置为需要认证才能访问(authc)。

2、认证和授权过滤器名称

1.认证过滤器名称

  • anon: 表示不需要登录,就可以访问资源
  • user: 表示必须用户登录后才能访问资源,当登入操作时不做检查()
  • authc: 表示需要登录认证才能访问资源,一般用于登录接口

2.授权过滤器名称

  • perms:例如/public/**=perms[user:add:*];参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/public/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
  • roles:例如/admin/**=roles[admin];参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admin/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

3、授权方式

主要有4种:

  • 编程式:通过 if/else 代码块来完成。
  • 注解式:通过在执行的方法上放置相应的注解来完成,没有权限则抛出相应异常。
  • 视图页面: 在视图页面(Beetl/JSP)通过相应的标签完成。
  • 基于URI拦截:根据URI匹配,决定访问权限。

下面主要介绍注解式和基于URI拦截。

1、编程式(具体到数据)

场景:编辑和审核共用一个资源,可以在资源内判断是否有审核权限,然后再去执行对应操作
具体应用例子:用户是否具有对列表中某一条或某一类数据进行操作的权限

Subject subject = UserUtils.getSubject();
subject.isAuthenticated();            // 是否身份验证授权通过
subject.isPermitted(permission);      // 验证权限字符串
subject.isPermittedAll(permissions);  // 验证权限字符串全部通过
subject.hasRole(roleIdentifier);      // 验证是否有角色权限

2、注解式(细粒度)

场景:对 URL 资源、按钮 等操作进行权限过滤,如果用户跳过了界面验证,直接去访问 URL 地址也需要经过授权验证的。
例如:用户具有用户管理的权限(但没具体说明是管理哪些用户)
具体应用例子:当前用户是否具有添加用户的权限(是否能请求添加接口)

在Controller的方法上指定如下注解:

  • @RequiresPermissions (value={“sys:user:view”, “sys:user:edit”}, logical= Logical.OR):表示当前 Subject 需要权限 user:view 或 user:edit。
  • @RequiresRoles(value={“admin”, “user”}, logical=Logical.AND):表示当前 Subject 需要角色 admin 和 user
  • @RequiresAuthentication:表示当前Subject已经通过login进行了身份验证;
  • @RequiresUser:表示当前 Subject 已经身份验证或者通过记住我登录的。
  • @RequiresGuest:表示当前Subject没有身份验证或通过记住我登录过,即是游客身份。

3、基于URI拦截(粗粒度)

场景:当不方便利用编程式、注解式等方式过滤权限时,可以使用 URI 控制权限,或全局控制某个 URI 地址的权限
例如:用户只允许修改部门A(不能修改B、C部门的用户)
具体应用例子:判断当前主体是否有权限访问某些页面

格式:
URI地址及通配符 = 过滤器名称(支持多个,用英文逗号分隔并加双引号)
以上权限过滤器定义配置,是依照由上到下的第一次匹配优先原则,优先匹配成功的URI优先受用,支持通配符。

三、补充:什么是粗颗粒和细颗粒权限?

  • 粗颗粒:对资源类型的管理称为粗颗粒度权限控制,即只控制到菜单、按钮、方法。
  • 细颗粒:对资源实例的控制称为细颗粒度权限管理,即控制到数据级别的权限。

猜你喜欢

转载自blog.csdn.net/weixin_42516475/article/details/130559783