apache Shiro学习笔记(三)Authorization

来源:互联网 发布:新手可以做淘宝代销吗 编辑:程序博客网 时间:2024/06/06 13:10

Authorization(Access control)

一、Authorization的元素:

  1. Permission(包括资源和动作(CRUD))
  2. Roles
    implicit roles:应用只提供一组基于角色名的权限(不建议)
    explicit roles:一组真正的权限表述的集合
  3. Users

二、编程式权限

  1. 基于角色的权限
    a)角色检查:hasRole*方法
    b)角色断言:checkRole*方法
  2. 基于权限的权限
    a)权限检查:isPermitted* 方法
    2.1 基于对象的权限检查:实现接口org.apache.shiro.authz.Permission
    优点:编译时类型安全、确保被正确地描述和使用、明确权限解析的逻辑运行、确保权限正确反映应用资源
    2.2 基于文本的权限检查:默认实现类org.apache.shiro.authz.permission.WildcardPermission
    b) 权限断言:checkPermission* 方法
  3. 基于注释的权限(需要aop支持)
    3.1 RequiresAuthentication注释:当前用户在当前Session中被认证,注释的类/实例/方法才会被允许调用
    3.2 RequiresGuest注释:当前用户是一个“Guest”,它没有被认证或者被先前的Session记住,被注释的类/实例/方法才会被允许调用
    3.3 RequiresPermissions(Permission)注释:当前用户被授于一个或多个权限来执行被注释的方法。
    3.4 RequiresRoles(Roles)注释:当前用户需要所有被指定的角色,如果没有,方法不会执行并抛出AuthorizationException异常。
    3.5 RequiresUser注释:当前用户是一个系统用户,注释的类/实例/方法才会被允许调用,系统用户是被定义的一个已知的标识或在认证当前Session期间被已经或通过先前Session的rememberMe服务已知。

三、授权的顺序

  1. 应用调用hasRole*,checkRole*,isPermitted*,hasPermission*方法,传入任意需要的角色或权限
  2. Subject实例,本质上是DelegatingSubject通过代理调用应用的SecurityManager各自的hasRole*,checkRole*,isPermitted*,hasPermission*方法。
  3. SecurityManager代理它内部的Authorizer实例各自的 hasRole*,checkRole*,isPermitted*,hasPermission*方法。在任何授权期间,Authorizer默认是一个ModularRealmAuthorizer实例用来支持装饰一个或者多个Realm实例
  4. 任何配置的Realm会检查时候继承于同一个Authorizer接口,如果是,Realm各自的hasRole*,checkRole*,isPermitted*,hasPermission*方法会被调用。

四、ModularRealmAuthorizer

他会迭代内部的Realm集合,通过迭代与每个Realm相互作用,和Realm的作用步骤如下:
1. 如果Realm本身实现Authorizer接口,它各自的hasRole*,checkRole*,isPermitted*,hasPermission*会被调用。
a)如果Realm的方法遭遇异常,异常会以AuthorizationException传递给Subject,这会短路这次授权过程,所用剩余的Realm不会被授权操作考虑
b)如果Realm的方法是hasRole*或isPermitted*方法,并且返回值是true,true值会被立刻返回,剩余的Realm会被短路。这作为增前性能存在,通常情况下,如果一个Realm被授权,暗示Subject被授权
2. 如果Realm没有实现Authorizer接口,被忽略。

五、Realm认证顺序

  1. 配置PermissionResolver,默认是WildCardPermissionResolver,如果想要实现自定义的PermissionResolver,需要实现PermissionResolverAware接口

    [main](全局配置)
    globalPermissionResolver=com.foo.bar.authz.MyPermissionResolver
    securityManager.authorizer.permissionResolver=$globarPermissionResolver

    [main](为每一个Realm配置)
    realm=com.foo.bar.realm.MyCustomerRealm
    realm.permissionResolver=$permissionResolver

  2. 配置RolePermissionResolver,如果想要实现自定义的RolePermissionResolver,需要实现RolePermissionResolverAware接口

    [main](全局配置)
    globalRolePermissionResolver=com.foo.bar.authz.MyPermissionResolver
    securityManager.authorizer.rolePermissionResolver=$globarPermissionResolver

    [main](为每一个Realm配置)
    realm=com.foo.bar.realm.MyCustomerRealm
    realm.rolePermissionResolver=$rolePermissionResolver

注:以上内容均为我从shiro官网上直接翻译,不能保证正确性