004-shiro授权

目录

授权三要素

授权方法

授权顺序

ModularRealmAuthorizer

PermissionResolver和RolePermissionResolver

WildcardPermission的规则简单介绍如下:


授权三要素

授权具有三个在Shiro中引用的核心元素:权限,角色和用户

权限:比如公司给你提供办公电脑,你可以使用该电脑,你的同事不能使用,但你不能将此电脑卖了换钱。(权限就是对某个资源的处理权。处理权分多种,这里就是使用和变卖)

角色:在公司来说,员工就是角色,领导也是角色,他不是具体的某个人,可以只某个岗位(研发、测试、产品),或者是某个部门(组织部、研发部),角色就是代表一类用户,在授权中,角色就是代表拥有某些共同权限的一类用户。

用户:用户是使用系统的用户,一般情况下,用户与角色绑定,角色与权限绑定,那么该用户拥有哪些权限自然就知道了。

三者的简单关系:一个用户可以拥有多个角色,一个角色拥有多个权限。有些系统可能角色和权限一起使用或者没有角色,直接将权限赋予用户。

授权方法

我们使用subject类的如下方法来进行权限认证:

  • boolean isPermitted(String var1);
    • 是否有某个权限
  • boolean isPermitted(Permission var1);
  • boolean[] isPermitted(String... var1);
    • 返回是否有对应权限的数组
  • boolean[] isPermitted(List<Permission> var1);
    • 同上
  • boolean isPermittedAll(String... var1);
    • 是否拥有列表中的所有权限
  • boolean isPermittedAll(Collection<Permission> var1);
    • 同上
  • void checkPermission(String var1) throws AuthorizationException;
    • 是否拥有权限(如果没有将抛出AuthorizationException异常)下同,依此类推
  • void checkPermission(Permission var1) throws AuthorizationException;
  • void checkPermissions(String... var1) throws AuthorizationException;
  • void checkPermissions(Collection<Permission> var1) throws AuthorizationException;
  • boolean hasRole(String var1);
  • boolean[] hasRoles(List<String> var1);
  • boolean hasAllRoles(Collection<String> var1);
  • void checkRole(String var1) throws AuthorizationException;
  • void checkRoles(Collection<String> var1) throws AuthorizationException;
  • void checkRoles(String... var1) throws AuthorizationException;

总结:has*方法,验证失败将返回false,而check*方法,验证失败将抛出AuthorizationException异常。实际使用中根据情况选用,大部分是使用check*方法让他抛出异常。

基于注释的授权

基于注解的授权需要你的程序是支持AOP的,我们常见的是在Spring的AOP框架下使用

RequiresAuthentication注解

调用被该注解修饰的方法时,subject是已认证的,其等效于SecurityUtils.getSubject().isAuthenticated() == true

@RequiresAuthentication
public void updateAccount(Account userAccount) {
    //需要是已认证的Subject才能调用该方法
    ...
}

RequiresGuest注解

允许游客访问

@RequiresGuest
public void signUp(User newUser) {
    //允许游客访问
    ...
}

其等效于如下代码:

Subject currentUser = SecurityUtils.getSubject();
PrincipalCollection principals = currentUser.getPrincipals();
if (principals != null && !principals.isEmpty()) {
      throw new AuthorizationException(...);
}

 RequiresPermissions注解

允许某个或某些权限访问

RequiresRoles注解

允许某个或某些角色访问

RequiresUser注解

允许已知身份的用户访问(Subject具有已知身份的,该身份是由于在当前会话期间进行了身份验证而已知的,或者是从先前会话的“ RememberMe”服务中记住的

关于注解的使用示例,我们将在后面的shiro的web集成中展示。此处了解即可。

 

授权顺序

  • 步骤1:应用程序或框架Subject所有如下方法( hasRole*,checkRole*,isPermitted*,或checkPermission*方法变体)进行权限或角色的授权验证。
  • 步骤2:一般情况下,程序中的Subject是DelegatingSubject(或其子类)调用上面的方法时,实际上是使用的SecurityManager的hasRole*,checkRole*,isPermitted*,或checkPermission*方法变体(securityManager而实现了org.apache.shiro.authz.Authorizer接口,hasRole*,checkRole*,isPermitted*,或checkPermission*方法变体这些方法是Authorizer接口的定义)。
  • 步骤3:在我们使用SecurityManager时。Authorizer接口默认实现是ModularRealmAuthorizer,该实例是一个实例,它支持Realm在任何授权操作期间协调一个或多个实例。
  • 步骤4:Realm检查每个已配置的配置,以查看是否实现了相同的Authorizer接口。如果是这样,ModularRealmAuthorizer调用该领域的各自的hasRole*,checkRole*,isPermitted*,或checkPermission*方法被调用。

总结:从上我们可以了解到,所有的认证权限的方法,最终都是调用的Realm中对应的hasRole*,checkRole*,isPermitted*,或checkPermission*方法

ModularRealmAuthorizer

上面我们提到,ModularRealmAuthorizer是Authorizer接口的默认实现,而且我们的SecurityManager也默认使用它,它来协调执行每个配置好的Realm。它的执行规则如下:

  • 如果Realm自身实现Authorizer接口,其各自的Authorizer对应的方法(hasRole*,checkRole*,isPermitted*,或checkPermission*)被调用。
    • 如果Realm的方法导致异常,则将抛出AuthorizationException异常给Subject调用方。这会缩短授权过程,并且该授权操作将不再执行任何剩余的领域。
    • 如果Realm的方法是返回布尔值的hasRole*或isPermitted*变体,并且返回值是true,则该true值将立即返回,并且所有剩余的Realms都将不再执行。
  • 如果Realm不实现该Authorizer接口,则将其忽略。

PermissionResolver和RolePermissionResolver

Resolver顾名思义,就是权限和角色的解析器(默认情况下,我们的权限或角色我们都直接通过字符串的形式进行表示,如果你需要自定义其他方式,或其他的解析方式,就需要使用这两个接口来实现--建议是使用默认方式就够了)

这两个接口都会将我们提供的角色或权限的字符串解析为Permission对象,Permission对象的默认实现是WildcardPermission,WildcardPermission定义了权限字符串的解析方式和定义规则。

一般情况下,我们的Realm会实现PermissionResolverAware和RolePermissionResolverAware两个接口,这两个接口提供了PermissionResolver和RolePermissionResolver的设置,如果我们自定义Resolver的话,就需要使用realm的对应的set方法进行设置。

WildcardPermission的规则简单介绍如下:

单个权限表示:query

多级的权限表示:

  • test:query:我们可以用test来表示菜单,query表示操作,该权限表示拥有test菜的的query操作权限
  • a:test:query:更多级的权限表示

"*"的使用:

  • test:*:表示我们可以使用test菜单下的所有操作(该权限表示包含了test:query权限)

上一篇:003-认证

下一篇:005-shiro的Realm源码解析与自定义Realm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值