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
用于判断是否已认证,未认证访问该资源会抛异常,下面代码效果相同
@RequiresAuthentication public void updateAccount(Account userAccount){ ... } public void updateAccount(Account userAccount){ if(!SecurityUtils.getSubject().isAuthenticated()){ throw new AuthorizationException(...); } }
@RequiresGuest
用于判断是否为游客,如果非游客会抛异常,下面代码效果相同
@RequiresGuest public 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
用于判断非游客才能访问,下面代码效果相同
@RequiresUser public 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对象
可以自定义解析器
原文地址:https://www.cnblogs.com/LiveYourLife/p/9092973.html