shiro 鉴权代码流程
前提条件
AuthorizingRealm的自定义子类的实现,主要重写鉴权方法代码
/**
*可以重写该方法,将特定用户跳过鉴权认证,返回true即可
*/
@Override
public boolean isPermitted(PrincipalCollection principals, String permission) {
return super.isPermitted(principals, permission);
}
/**
* (验证权限时调用)
* principals 用户信息
* 设置授权信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
String userId = user.getId();
//用户权限列表
Set<String> permsSet = shiroService.getUserPermissions(userId);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permsSet);
return info;
}
具体流程 :
当前端访问controller方法时,如果方法上有 @RequiresPermissions 注解,则代表调用该方法前会被拦截器拦截,校验改用户权限
@SysLog("删除定时任务")
@PostMapping("/delete")
@RequiresPermissions("sys:schedule:delete")
public R delete(@RequestBody String[] jobIds){
scheduleJobService.deleteBatch(jobIds);
return R.ok();
}
org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor#assertAuthorized (拦截器)
org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor#assertAuthorized
org.apache.shiro.authz.aop.PermissionAnnotationHandler#assertAuthorized
org.apache.shiro.subject.support.DelegatingSubject#checkPermission
org.apache.shiro.mgt.AuthorizingSecurityManager#checkPermission
org.apache.shiro.authz.ModularRealmAuthorizer#checkPermission
org.apache.shiro.authz.ModularRealmAuthorizer#isPermitted
这一步就会调用到我们最开始重写的方法:
重写方法如下,如果是管理员用户,则直接返回true,不做鉴权(此处逻辑为重写的业务逻辑),如果非管理员,则调用父类的isPermitted方法
org.apache.shiro.realm.AuthorizingRealm#isPermitted (父类方法)
org.apache.shiro.realm.AuthorizingRealm#getAuthorizationInfo 调用最开始realm的重写鉴权方法,进行权限查看
重写方法(查看该用户的权限列表)
将改请求与权限列表进行比对,验证是否有权限进行访问 org.apache.shiro.realm.AuthorizingRealm#isPermitted
返回true则代表有权限
]
将改请求与权限列表进行比对,验证是否有权限进行访问 org.apache.shiro.realm.AuthorizingRealm#isPermitted
返回true则代表有权限