用户分组权限管理模块的设计

[b]接口和抽象类的设计[/b]


//身份解决者接口
public interface IdentityResolver {
public boolean isLoggedIn(HttpServletRequest req);
}
//许可解决者接口
public interface PermissionResolver {
//判断许可解决者和被许可对象是否匹配
public boolean match(String permissionStr);
//这里返回Boolean或者整数可能能够支持更复杂的许可逻辑,比如一票否决,带权重许可,这方面我缺乏业务经验。暂且不表
public boolean hasPermission(HttpServletRequest req);
}

//许可解决者抽象类,这里的实现是使用类似于 xxxx.yyyy.zzzz 的字符串来代表分层的授权,通配符*代表某层的所有权限
public abstract class PermissionResolverAbstract implements PermissionResolver {
protected abstract String getMatch();
protected Pattern pattern;
@Override
public boolean match(String permissionStr){
if(pattern==null){
String regEx = getMatch().replaceAll("\\*+", "\\\\S*").replaceAll("\\-", "\\\\-").replaceAll("\\.", "\\\\.");
regEx = new StringBuilder("^").append(regEx).append("$").toString();
pattern = Pattern.compile(regEx);
}
return pattern.matcher(permissionStr).matches();
}
}



权限工具类

public class Security {

private final List<IdentityResolver> identityResolverList = new ArrayList<>();
private final List<PermissionResolver> permissionResolverList = new ArrayList<>();
//缓存
private final Map<String, List<PermissionResolver>> permissionResolverMap = new ConcurrentHashMap<>();
private boolean skip = false;//是否关闭授权系统,这里应该读取配置文件,不是写死在代码中

public Security() {
}

public void addIdentityResolver(IdentityResolver identityResolver) {
identityResolverList.add(identityResolver);
}

public void addPermissionResolver(PermissionResolver permissionResolver) {
permissionResolverList.add(permissionResolver);
}

public boolean isLoggedIn(HttpServletRequest req) {
if (skip) {
return true;
}
return _isLoggedIn(req);
}

public boolean hasPermission(String permissionStr,boolean checkLoggedIn, HttpServletRequest req) {
if (skip) {
return true;
}
if (checkLoggedIn && !_isLoggedIn(req)) {
return false;
}
return _hasPermission(permissionStr, req);
}

public boolean hasPermission(String permissionStr, HttpServletRequest req) {
return hasPermission(permissionStr,false, req);
}

private boolean _isLoggedIn(HttpServletRequest req) {
for(IdentityResolver identityResolver :identityResolverList){
if(identityResolver.isLoggedIn(req)){
return true;
}
}
return false;
}

private boolean _hasPermission(String permissionStr, HttpServletRequest req) {
if (!permissionResolverMap.containsKey(permissionStr)) {
List<PermissionResolver> prs = new ArrayList<>();
//将与授权对象匹配的权限解决者实现添加进队列,这里用简单list,是否使用责任链或者其他设计模式,值得斟酌
for (PermissionResolver pr : permissionResolverList) {
if (pr.match(permissionStr)) {
prs.add(pr);
}
}
//缓存,时间和空间的平衡
permissionResolverMap.put(permissionStr, prs);
}
for (PermissionResolver pr : permissionResolverMap.get(permissionStr)) {
if (pr.hasPermission(req)) {
return true;
}
}
return false;
}

}


业务逻辑中的调用代码:

servlet上下文监听器中

Security security = new Security();

//身份解决者 和 许可解决者 的具体实现应该单独打包封装对应不同的业务
IdentityResolver identityResolver = new IdentityResolverImpl();
PermissionResolver allPR =new AllPR();
...

//添加身份解决者进入队列
security.addIdentityResolver(identityResolver);
...
//添加许可解决者进入队列
security.addPermissionResolver(allPR);
...


业务逻辑调用示例

//messages 为消息对象
public static boolean isLoggedIn(Security security, HttpServletRequest req, Messages messages) {
if (!security.isLoggedIn(req)) {
String msg = "请登录执行本操作";
messages.add(Message.Severity.WARN, msg, msg);
return false;
}
return true;
}

public static boolean hasPermission(String p, Security security, HttpServletRequest req, Messages messages) {
if (!isLoggedIn(security, req, messages)) {
return false;
} else if (!security.hasPermission(p, req)) {
String msg = "你无权执行本操作";
messages.add(Message.Severity.WARN, msg, msg);
return false;
}
return true;
}


[b]相关阅读:[/b]
我的java web架构方案 [url]http://afadgaeg.iteye.com/admin/blogs/2395132[/url]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值