shiro授权设计的两种思路
其实过滤器就是一级一级的筛选匹配,通过后放行
用authc 表示访问资源需要验证登录
用roles表示访问资源需要角色匹配成功
用perms表示访问角色需要perms中的匹配到
方式一:一般的权限设计用authc+roles即可(也可精确到按钮),
方式二:还可authc+perms 此时就是用户的资源和perms中的资源匹配
方式一:
所有用户及对应的资源信息在初始化的时候就加载到每台机器的内存,验证通过的情况下,授权时用户自身的信息每次请求一次每次从新加载(url,角色 分开),用户请求url,
在服务器中找此用户访问此url对应的role[].此资源要求的角色role[]和当前用户的角色(subject中有(role,perm,principal(用户信息)))是否匹配
subject中的role用来走roles过滤器验证角色条件
subject中的permission用来走perm过滤器用来验证perm需要的条件
subject中的principal用来存储用户登录信息
当前用户的subject中的信息来源:组织用户的role,perm,这种实现只需要role角色
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//得到 doGetAuthenticationInfo 方法中传入的凭证
FinancialSalesUser shiroUser = (FinancialSalesUser) principals.fromRealm(getName()).iterator().next();
List<String> roleList = new ArrayList<String>();
List<String> permissionList = new ArrayList<String>();
String userName = shiroUser.getUserName();
List<FinancialSalesUserRole> selectedRoleList = new ArrayList();
if(null!=shiroUser){
selectedRoleList = this.financialSalesUserFacade.selectUserRole(shiroUser.getId());
if (null != selectedRoleList && selectedRoleList.size() > 0) {
for(FinancialSalesUserRole r: selectedRoleList){
roleList.add(r.getRoleId()+"");
FinancialSalesUserRoleCondition financialSalesRoleCondition =new FinancialSalesUserRoleCondition();
financialSalesRoleCondition.setRoleId(r.getRoleId()+"");
List<Map> branchArr = financialSalesRoleFacade.getRoleFuncUrl(financialSalesRoleCondition);
if (null != branchArr&& branchArr.size() > 0) {
for (Iterator<Map> it = branchArr.iterator(); it.hasNext();) {//遍历角色菜单
Map resource = it.next();
if (!"".equals(resource)&&resource!=null) {
permissionList.add(resource.get("url")+"");
}
}
}
}
}
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//这个确定页面�?<shiro:hasRole>标签的name的�??
info.addRoles(roleList);
//这个就是页面�? <shiro:hasPermission> 标签的name的�??
info.addStringPermissions(permissionList);
return info;
}
role过滤器的验证过程:
单个用户的只需要角色信息即可(之前做的也有单个用户的url信息),所有用户的即需要资源,有需要 角色
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception
{
Subject subject = getSubject(request, response);
HttpServletRequest request1 =(HttpServletRequest) ((WebSubject) SecurityUtils.getSubject()).getServletRequest(); //ServletActionContext.getRequest();
Cookie[] cookies = request1.getCookies();
String username1=getCookieValue(cookies, "username");
//String uk="Subject"+username1;
//Subject currentUserrds=(Subject)webSession.getAttribute(uk);
String uk="request";
String rk="response";
//byte[] request2=(byte[])webSession.getAttribute(uk+username1);
//byte[] response1=(byte[])webSession.getAttribute(rk+username1);
//
//ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new java.io.ByteArrayInputStream(request2)));
//HttpServletRequest user = (HttpServletRequest) ois.readObject();
//if(request2!=null&&response1!=null){
////subject= getSubject(user, response1);
//}
String[] rolesArray = (String[])mappedValue;
if ((rolesArray == null) || (rolesArray.length == 0))
{
return true;
}
// Set<String> roles = CollectionUtils.asSet(rolesArray);
boolean flag=false;
String[] roles = (String[])rolesArray[0].split(",");
for(int i=0;i<roles.length;i++){
System.out.println(roles[i]);
if(subject.hasRole(roles[i])){
return subject.hasRole(roles[i]);
}
}
return flag;
}
方式 二:
全局所有用户的资源及对应要求的perm信息加载到内存中,组装好此用户的perm信息,当用户访问资源时,用户的perm信息和此访问资源对应要求的perm匹配,有的话通过
即授权的时候不通过角色,但是我们在设计组织数据的时候,还是要通过用户关联角色,角色关联资源,只是匹配的时候只去用户的perm和数据库中的perm即可
当前用户的subject中的信息来源:用户的perm信息组织:这种权限思路只需要perm
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user= (User) SecurityUtils.getSubject().getPrincipal();//User{id=1, username='admin', password='3ef7164d1f6167cb9f2658c07d3c2f0a', enable=1}
Map<String,Object> map = new HashMap<String,Object>();
map.put("userid",user.getId());
List<Resources> resourcesList = resourcesService.loadUserResources(map);
// 权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for(Resources resources: resourcesList){
info.addStringPermission(resources.getResurl());
}
return info;
}
perm的过滤器验证过程:
protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
Collection<Permission> perms = getPermissions(info);
if (perms != null && !perms.isEmpty()) {
for (Permission perm : perms) {
if (perm.implies(permission)) {
return true;
}
}
}
return false;
}