现在在前端加上shiro的标签: shiro:hasPermission=“aaa”,访问该页面时,检测到shiro的标签,那么就会进入后端shiro的权限校验:
DelegatingSubject 实现 Subject接口,里面有个isPermitted(String permission)方法,其中permission参数就是前端获取到的aaa
public boolean isPermitted(String permission) {
return this.hasPrincipals() && this.securityManager.isPermitted(this.getPrincipals(), permission);
}
//验证Principals是否为空
protected boolean hasPrincipals() {
return !isEmpty(this.getPrincipals());
}
public PrincipalCollection getPrincipals() {
List<PrincipalCollection> runAsPrincipals = this.getRunAsPrincipalsStack();
return CollectionUtils.isEmpty(runAsPrincipals) ? this.principals : (PrincipalCollection)runAsPrincipals.get(0);
}
然后进入securityManager.isPermitted(this.getPrincipals(), permission)方法,实际进入AuthorizingSecurityManager类,该类是securityManager接口的实现类:
public boolean isPermitted(PrincipalCollection principals, String permissionString) {
return this.authorizer.isPermitted(principals, permissionString);
}
调用authorizer.isPermitted(principals, permissionString),进入authorizer的实现类ModularRealmAuthorizer:
public boolean isPermitted(PrincipalCollection principals, String permission) {
this.assertRealmsConfigured();
Iterator var3 = this.getRealms().iterator();
Realm realm;
do {
if (!var3.hasNext()) {
return false;
}
realm = (Realm)var3.next();
} while(!(realm instanceof Authorizer) || !((Authorizer)realm).isPermitted(principals, permission));
return true;
}
获取到一个realm的对象,该对象是Authorizer的一个实例,调用((Authorizer)realm).isPermitted(principals, permission))方法,实际是进入AuthorizingRealm类:
public boolean isPermitted(PrincipalCollection principals, String permission) {
Permission p = this.getPermissionResolver().resolvePermission(permission);
return this.isPermitted(principals, p);
}
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
AuthorizationInfo info = this.getAuthorizationInfo(principals); //根据登录的用户信息获取权限
return this.isPermitted(permission, info);
}
//获取到用户的权限信息,该方法将权限信息和传入的permission进行比较,
protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
Collection<Permission> perms = this.getPermissions(info);
if (perms != null && !perms.isEmpty()) {
Iterator var4 = perms.iterator();
while(var4.hasNext()) {
Permission perm = (Permission)var4.next();
if (perm.implies(permission)) {
return true;
}
}
}
上段代码中的this.getAuthorizationInfo(principals)方法进入自己编写的类MyShiroRealm extends AuthorizingRealm,这里就是实现获取权限信息的过程:
@Override
//登录进入有principals的缓存cn.com.soyea.common.core.entity.vo.UserVO@42ff0600
public AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
if (null == principals) {
return null;
} else {
//根据用户名从缓存中读取权限信息
AuthorizationInfo authorizationInfo = super.getAuthorizationCache().get(((User) principals.getPrimaryPrincipal()).getUserName());
if (null == authorizationInfo) {
//重新获取权限信息
authorizationInfo = this.doGetAuthorizationInfo(principals);
return authorizationInfo;
} else {
//获取缓存中权限的perms和roles
Set<String> perms = (Set<String>) authorizationInfo.getStringPermissions();
Set<String> roles = (Set<String>) authorizationInfo.getRoles();
if (perms == null || perms.size() == 0 || roles == null || roles.size() == 0) {
//perms或roles为null,重新获取权限信息
authorizationInfo = this.doGetAuthorizationInfo(principals);
return authorizationInfo;
} else {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(perms);
info.addRoles(roles);
return info;
}
}
}
}
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Object principal = principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
if (principal instanceof UserVO) {
UserVO userVO = (UserVO) principal;
List<Role> roleList = userVO.getRoleList();
if (null != roleList && roleList.size() > 0) {
Set<String> roles = new HashSet<>();
Set<String> permissions = new HashSet<>();
for (Role role : roleList) {
roles.add(role.getRoleName());
R r =xxx.getResourcesByRoleId(role.getId());
if (null == r || !r.get("code").toString().equals("200") || !r.containsKey("data") || null == r.get("data")) {
return null;
}
List<Resource> resourceList = R.getListData(r, Resource.class);
if (null != resourceList && 0 < resourceList.size()) {
for (int i = 0; i < resourceList.size(); i++) {
permissions.add(resourceList.get(i).getResourcePerm());
}
}
}
authorizationInfo.addStringPermissions(permissions);
authorizationInfo.addRoles(roles);
//获取缓存对象,并向对象中注入新的用户名和info
super.getAuthorizationCache().put(userVO.getUserName(), authorizationInfo);
}
}
return authorizationInfo;
}