1、授权实现方式
1.1、什么是授权
授权包含4个元素(一个比较流行通用的权限模型)
Resources:资源
各种需要访问控制的资源
Permissions:权限
安全策略控制原子元素
基于资源和动作
控制力度
Roles:角色
行为的集合
User:用户主体
Subject,关联Role或Permission
简单来说,可以这样理解:我们登录进系统,我们就是一个【用户】;【用户】可以是一个或多个【角色】,一个【角色】可以有多种【权限】,这些【权限】代表了我们可以访问哪些【资源】。当然【用户】也可以直接跳过【角色】,直接给【用户】分配【权限】,表明这个【用户】可以访问的【资源】。
1.2、授权方式
a、编程模型
基于Role
Role校验
API:
hasRole(String roleName)
hasRoles(List<String> roleNames)
hasAllRoles(Collection<String> roleNames)
Subject currentUser = SecurityUtils.getSubject();if(currentUser.hasRole("admin")){ ???...} else{ ???...}
Role断言(Assertion)
失败会抛出异常AuthorizationException
API
checkRole(String roleName)
checkRoles(Collection<String> roleNames)
checkRoles(String... roleNames)
Subject currentUser = SecurityUtils.getSubject();currentUser.checkRole("bankTeller");openBankAccount();
基于Permission
Permission校验
基于对象的Permission校验
应用场景:显式控制、类型安全
API
isPermiited(Permission p)
isPermiited(List<Permission> perms)
isPermiitedAll(Collection<Permission> perms)
Permission printPermission = new PrinterPermission("hp","print");Subject currentUser = SecurityUtils.getSubject();if(currentUser.isPermitted(printPermission)){ ???...} else { ???...}
基于String的Permission校验
应用场景:轻量级、简单
API
isPermiited(String perm)
isPermiited(String... perms)
isPermiitedAll(String... perms)
Subject currentUser = SecurityUtils.getSubject();if(currentUser.isPermitted("printer:print:hp")){ ???...} else { ???...}
Permission断言(Assertion)
失败会抛出异常AuthorizationException
API
checkPermission(Permission p))
checkPermission(String perm)
checkPermissions(Collection<Permission> perms)
checkPermissions(String... perms)
Subject currentUser = SecurityUtils.getSubject();Permission p = new AccountPermission("open");current.checkPermission(p);openBankAccount();
b、JDK注解
@RequiresAuthentication
用于判断是否已认证,未认证访问该资源会抛异常,下面代码效果相同
@RequiresAuthenticationpublic void updateAccount(Account userAccount){ ???...}public void updateAccount(Account userAccount){ ???if(!SecurityUtils.getSubject().isAuthenticated()){ ???????throw new AuthorizationException(...); ???}}
@RequiresGuest
用于判断是否为游客,如果非游客会抛异常,下面代码效果相同
@RequiresGuestpublic void signUp(User newUser){ ???...}public void signUp(User newUser){ ???Subject currentUser = SecurityUtils.getSubject(); ???PrincipalCollection principals = currentUser.getPrincipals(); ???if(principals != null && !principals.isEmpty()){ ???????throw new AuthorizationException(...); ???}}
@RequiresPermissions
用于判断有该权限才能访问,下面代码效果相同
@ReruiresPermissions("account:create")public void creatAccount(Account account){ ???...}public void creatAccount(Account account){ ???Subject currentUser = SecurityUtils.getSubject(); ???if(!subject.isPermitted("account:create")){ ???????throw new AuthorizationException(...); ???}}
@RequiresRoles
用于判断有该角色才能访问,下面代码效果相同
@RequiresRoles("admin")public void deleteUser(User user){ ???...}public void deleteUser(User user){ ???Subject currentUser = SecurityUtils.getSubject(); ???if(!subject.hasRole("admin")){ ???????throw new AuthorizationException(...); ???}}
@RequiresUser
用于判断非游客才能访问,下面代码效果相同
@RequiresUserpublic void updateAccount(Account account){ ???...}public void updateAccount(Account account){ ???Subject currentUser = SecurityUtils.getSubject(); ???PrincipalCollection principals = currentUser.getPrincipals(); ???if(principals == null || principals.isEmpty()){ ???????throw new AuthorizationException(...); ???}}
c、JSP/GSP TagLibs
偏向web,不介绍
2、授权架构
1、调用Subject的isPermitted或HasRole方法
2、找Security Manager(门面模式)
3、调用Authorizer组件
4、通过Realm访问数据库等获取数据,用于判断是否有授权
Authorizer
默认实现ModularRealmAuthorizer
迭代授权多个Realm
策略
如果一个Realm不实现Authorizer,不校验
如果一个Realm实现Authorizer
一旦校验失败,马上抛AuthorizationException
一旦校验成功,马上返回true
PermissionResolver权限解析器
用于将Permission字符串解析成Permission对象,Shiro内部都是使用Permission对象来进行验证
默认WildcardPermissionResolver(通配符权限解析器)
可以自定义解析器
RolePermissionResolver
用于将Role字符串转换为Permission对象
可以自定义解析器
【Shiro】四、Apache Shiro授权
原文地址:https://www.cnblogs.com/LiveYourLife/p/9092973.html