Shiro的内部处理机制。
Shiro架构图的授权部分,来说明Shiro授权内部的处理顺序:
Subject 的hasRole*, checkRole*, isPermitted*, 或者checkPermission*方法的变体,传递任何所需的权限或角色内容。
的实例,通常是DelegatingSubject (或子类)代表应用程序的SecurityManager 通过调用securityManager的各自相同的hasRole*, checkRole*, isPermitted*,或checkPermission*方法的变体(SecurityManager 实现org.apache.shiro.authz.Authorizer 接口,他定义了所有Subject 具体的授权方法)。
,作为一个基本的“保护伞”组件,接替/代表它内部的org.apache.shiro.authz.Authorizer实例通过调用authorizer 各自的hasRole*, checkRole*, isPermitted*, 或者checkPermissions*方法。默认情况下,authorizer 实例是一个ModularRealmAuthorizer 实例,它支持协调任何授权操作过程中的一个或多个Realm 实例。
Realm 被检查是否实现了相同的Authorizer 接口。如果是,Realm 各自的hasRole*, checkRole*,isPermitted*,或checkPermission*方法将被调用。
Shiro SecurityManager 的默认实现是使用一个ModularRealmAuthorizer 实例。ModularRealmAuthorizer 同样支持单一的Realm,以及多个Realm 的应用。
ModularRealmAuthorizer 将遍历其内部的Realm 集合,并按顺序与每一个进行交互。每个Realm 的交互功能如下:如果Realm 自己实现了Authorizer 接口,它的各个Authorizer 方法(hasRole*, checkRole*, isPermitted*, 或checkPermission*)将被调用;如果Realm 不实现Authorizer 接口,它会被忽略。
Realms时,ModularRealmAuthorizer 根据SecurityManager 的配置获得对Realm 实例的访问。当执行授权操作时,它会遍历该集合,同时对于每一个自己实现Authorizer 接口的Realm,调用Realm 各自的Authorizer 方法(如hasRole*, checkRole*,isPermitted*,或checkPermission*)。
Realm 的方法导致异常,该异常将会以AuthorizationException 的形式传递给调用者。同时任何剩余的Realm 将不会被该授权操作所访问。如果该Realm 的方法是一个返回布尔值的hasRole*或者isPermitted*的变体,并且该返回值为true,真值将会立即被返回,同时任何剩余的Realm 都将不会访问。这种处理是作为提高性能的一种行为。
Shiro默认实现是将该字符串转换成一个实际的Permission 实例。所有Shiro Realm 的默认实现是内部的WildcardPermissionResolver,它采用Shiro 的WildcardPermission 字符串格式。你也可以创建自己的PermissionResolver 的实现,支持自己的权限字符串语法。可以将你的PermissionResolver 设置为全局的。例如:
|
Realm设置自己创建的PermissionResolver。例如:
|
PermissionResolver 有相似概念的RolePermissionResolver 通过角色执行权限检查。RolePermissionResolver 的关键区别是输入的字符串是一个角色名,而不是一个权限字符串。
Shiro 中授权有3种方式:
Java 代码中用像if 和else 块的结构执行授权检查。
的注解——你可以添加授权注解给你的Java 方法。
标签库——你可以控制基于角色和权限的JSP 或者GSP 页面输出。