去shiro 基本完成

This commit is contained in:
zhouhao
2017-08-16 22:44:07 +08:00
parent eccb37128f
commit 12847e4cf9
27 changed files with 125 additions and 188 deletions

View File

@@ -3,10 +3,11 @@ package org.hswebframework.web.authorization.basic.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.hswebframework.web.AopUtils;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.basic.handler.AuthorizingContext;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.authorization.basic.handler.AuthorizingHandler;
import org.hswebframework.web.authorization.define.AuthorizeDefinition;
import org.hswebframework.web.authorization.exception.AuthorizationException;
import org.hswebframework.web.authorization.exception.UnAuthorizedException;
import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
@@ -31,7 +32,7 @@ public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor
if (null != definition) {
AuthorizingContext context = new AuthorizingContext();
context.setAuthentication(Authentication.current().orElseThrow(AuthorizationException::new));
context.setAuthentication(Authentication.current().orElseThrow(UnAuthorizedException::new));
context.setDefinition(definition);
context.setParamContext(paramContext);
authorizingHandler.handle(context);

View File

@@ -1,5 +1,7 @@
package org.hswebframework.web.authorization.basic.handler;
import org.hswebframework.web.authorization.define.AuthorizingContext;
/**
* aop方式权限控制处理器
* @author zhouhao

View File

@@ -10,6 +10,7 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessController;
import org.hswebframework.web.authorization.annotation.Logical;
import org.hswebframework.web.authorization.define.AuthorizeDefinition;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.authorization.exception.AuthorizationException;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
import org.slf4j.Logger;
@@ -47,21 +48,21 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
handleRdac(context.getAuthentication(), context.getDefinition());
//进行数据权限控制
handleDataAccess(context.getAuthentication(), context.getDefinition(), context.getParamContext());
handleDataAccess(context);
//表达式权限控制
handleExpression(context.getAuthentication(), context.getDefinition(), context.getParamContext());
}
protected void handleDataAccess(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorParamContext paramContext) {
protected void handleDataAccess(AuthorizingContext context) {
if (dataAccessController == null) {
logger.warn("dataAccessController is null,skip data access control!");
return;
}
List<Permission> permission = authentication.getPermissions()
List<Permission> permission = context.getAuthentication().getPermissions()
.stream()
.filter(per -> definition.getPermissions().contains(per.getId()))
.filter(per -> context.getDefinition().getPermissions().contains(per.getId()))
.collect(Collectors.toList());
DataAccessController finalAccessController = dataAccessController;
@@ -70,18 +71,16 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
Set<DataAccessConfig> accesses = permission
.stream().map(Permission::getDataAccesses)
.flatMap(Collection::stream)
.filter(access -> definition.getActions().contains(access.getAction()))
.filter(access -> context.getDefinition().getActions().contains(access.getAction()))
.collect(Collectors.toSet());
//无规则,则代表不进行控制
if (accesses.isEmpty()) return;
//单个规则验证函数
Function<Predicate<DataAccessConfig>, Boolean> function =
definition.getLogical() == Logical.AND ?
accesses.stream()::allMatch : accesses.stream()::anyMatch;
Function<Predicate<DataAccessConfig>, Boolean> function = accesses.stream()::allMatch;
//调用控制器进行验证
boolean isAccess = function.apply(access -> finalAccessController.doAccess(access, paramContext));
boolean isAccess = function.apply(access -> finalAccessController.doAccess(access, context));
if (!isAccess) {
throw new AuthorizationException(definition.getMessage());
throw new AuthorizationException(context.getDefinition().getMessage());
}
}
@@ -113,8 +112,10 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
protected void handleRdac(Authentication authentication, AuthorizeDefinition definition) {
boolean access = true;
//多个设置时的判断逻辑
Logical logical = definition.getLogical() == Logical.DEFAULT ? Logical.OR : definition.getLogical();
boolean logicalIsOr = logical == Logical.OR;
Set<String> permissionsDef = definition.getPermissions();
Set<String> actionsDef = definition.getActions();
Set<String> rolesDef = definition.getRoles();

View File

@@ -21,6 +21,7 @@ package org.hswebframework.web.authorization.basic.handler.access;
import org.hswebframework.web.authorization.access.CustomDataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessHandler;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
/**
@@ -37,7 +38,7 @@ public class CustomDataAccessHandler implements DataAccessHandler {
}
@Override
public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
public boolean handle(DataAccessConfig access, AuthorizingContext context) {
CustomDataAccessConfig custom = ((CustomDataAccessConfig) access);
return custom.getController().doAccess(access, context);
}

View File

@@ -3,6 +3,7 @@ package org.hswebframework.web.authorization.basic.handler.access;
import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessController;
import org.hswebframework.web.authorization.access.DataAccessHandler;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
import java.util.LinkedList;
@@ -36,12 +37,12 @@ public final class DefaultDataAccessController implements DataAccessController {
}
@Override
public boolean doAccess(DataAccessConfig access, MethodInterceptorParamContext params) {
if (parent != null) parent.doAccess(access, params);
public boolean doAccess(DataAccessConfig access, AuthorizingContext context) {
if (parent != null) parent.doAccess(access, context);
return handlers.stream()
// TODO: 17-3-28 可以换成access对应的handler以提高效率
.filter(handler -> handler.isSupport(access))
.allMatch(handler -> handler.handle(access, params));
.allMatch(handler -> handler.handle(access, context));
}
public DefaultDataAccessController addHandler(DataAccessHandler handler) {

View File

@@ -5,6 +5,7 @@ import org.hswebframework.web.authorization.Permission;
import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessHandler;
import org.hswebframework.web.authorization.access.FieldFilterDataAccessConfig;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
import org.hswebframework.web.commons.entity.Entity;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
@@ -12,6 +13,8 @@ import org.hswebframework.web.commons.model.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* 数据权限字段过滤处理,目前仅支持deny. {@link DataAccessConfig.DefaultType#DENY_FIELDS}
*
@@ -22,11 +25,11 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
@Override
public boolean isSupport(DataAccessConfig access) {
return access instanceof FieldFilterDataAccessConfig && DataAccessConfig.DefaultType.DENY_FIELDS.equals(access.getType());
return access instanceof FieldFilterDataAccessConfig;
}
@Override
public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
public boolean handle(DataAccessConfig access, AuthorizingContext context) {
FieldFilterDataAccessConfig filterDataAccessConfig = ((FieldFilterDataAccessConfig) access);
switch (access.getAction()) {
@@ -48,10 +51,11 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
* @see BeanUtilsBean
* @see org.apache.commons.beanutils.PropertyUtilsBean
*/
protected boolean doUpdateAccess(FieldFilterDataAccessConfig accesses, MethodInterceptorParamContext params) {
Object supportParam = params.getParams().values().stream()
.filter(param -> (param instanceof Entity) | (param instanceof Model))
.findAny().orElse(null);
protected boolean doUpdateAccess(FieldFilterDataAccessConfig accesses, AuthorizingContext params) {
Object supportParam = params.getParamContext().getParams().values().stream()
.filter(param -> (param instanceof Entity) || (param instanceof Model)||(param instanceof Map))
.findAny()
.orElse(null);
if (null != supportParam) {
for (String field : accesses.getFields()) {
try {
@@ -64,14 +68,14 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
}
}
} else {
logger.warn("doUpdateAccess skip ,because can not found any entity in param!");
logger.warn("doUpdateAccess skip ,because can not found any support entity in param!");
}
return true;
}
protected boolean doQueryAccess(FieldFilterDataAccessConfig access, MethodInterceptorParamContext context) {
QueryParamEntity entity = context.getParams()
protected boolean doQueryAccess(FieldFilterDataAccessConfig access, AuthorizingContext context) {
QueryParamEntity entity = context.getParamContext().getParams()
.values().stream()
.filter(QueryParamEntity.class::isInstance)
.map(QueryParamEntity.class::cast)

View File

@@ -9,6 +9,7 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessHandler;
import org.hswebframework.web.authorization.access.FieldScopeDataAccessConfig;
import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.QueryController;
@@ -33,9 +34,9 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
}
@Override
public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
public boolean handle(DataAccessConfig access, AuthorizingContext context) {
FieldScopeDataAccessConfig own = ((FieldScopeDataAccessConfig) access);
Object controller = context.getTarget();
Object controller = context.getParamContext().getTarget();
if (controller != null) {
switch (access.getAction()) {
case Permission.ACTION_QUERY:
@@ -55,10 +56,9 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
}
@SuppressWarnings("unchecked")
protected boolean doRWAccess(FieldScopeDataAccessConfig access, MethodInterceptorParamContext context, Object controller) {
protected boolean doRWAccess(FieldScopeDataAccessConfig access, AuthorizingContext context, Object controller) {
//获取注解
RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
Object id = context.getParamContext().<String>getParameter(context.getDefinition().getDataAccessDefinition().getIdParameterName()).orElse(null);
//通过QueryController获取QueryService
//然后调用selectByPk 查询旧的数据,进行对比
if (controller instanceof QueryController) {
@@ -80,8 +80,8 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
}
protected boolean doQueryAccess(FieldScopeDataAccessConfig access, MethodInterceptorParamContext context) {
QueryParamEntity entity = context.getParams()
protected boolean doQueryAccess(FieldScopeDataAccessConfig access, AuthorizingContext context) {
QueryParamEntity entity = context.getParamContext().getParams()
.values().stream()
.filter(QueryParamEntity.class::isInstance)
.map(QueryParamEntity.class::cast)

View File

@@ -2,14 +2,11 @@ package org.hswebframework.web.authorization.basic.handler.access;
import org.hsweb.ezorm.core.param.Term;
import org.hswebframework.utils.ClassUtils;
import org.hswebframework.web.AuthorizeException;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.Permission;
import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessHandler;
import org.hswebframework.web.authorization.access.OwnCreatedDataAccessConfig;
import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.commons.entity.Entity;
import org.hswebframework.web.commons.entity.RecordCreationEntity;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
@@ -35,9 +32,9 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
}
@Override
public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
public boolean handle(DataAccessConfig access, AuthorizingContext context) {
OwnCreatedDataAccessConfig own = ((OwnCreatedDataAccessConfig) access);
Object controller = context.getTarget();
Object controller = context.getParamContext().getTarget();
if (controller != null) {
switch (access.getAction()) {
case Permission.ACTION_QUERY:
@@ -45,7 +42,7 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
case Permission.ACTION_GET:
case Permission.ACTION_DELETE:
case Permission.ACTION_UPDATE:
return doRWAccess(own, context, controller);
return doRWAccess(own, context,controller);
case Permission.ACTION_ADD:
//put creator_id to data
return putCreatorId(own, context);
@@ -58,16 +55,14 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
return true;
}
public boolean putCreatorId(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context) {
RecordCreationEntity entity = context.getParams()
public boolean putCreatorId(OwnCreatedDataAccessConfig access, AuthorizingContext context) {
RecordCreationEntity entity = context.getParamContext().getParams()
.values().stream()
.filter(RecordCreationEntity.class::isInstance)
.map(RecordCreationEntity.class::cast)
.findAny().orElse(null);
if (entity != null) {
entity.setCreatorId(Authentication.current()
.orElseThrow(AuthorizeException::new)
.getUser().getId());
entity.setCreatorId(context.getAuthentication().getUser().getId());
} else {
logger.warn("try put creatorId property,but not found any RecordCreationEntity!");
}
@@ -75,10 +70,9 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
}
@SuppressWarnings("unchecked")
protected boolean doRWAccess(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context, Object controller) {
protected boolean doRWAccess(OwnCreatedDataAccessConfig access, AuthorizingContext context, Object controller) {
//获取注解
RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
Object id = context.getParamContext().<String>getParameter(context.getDefinition().getDataAccessDefinition().getIdParameterName()).orElse(null);
//通过QueryController获取QueryService
//然后调用selectByPk 查询旧的数据,进行对比
if (controller instanceof QueryController) {
@@ -88,7 +82,7 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
QueryService<RecordCreationEntity, Object> queryService =
((QueryController<RecordCreationEntity, Object, Entity>) controller).getService();
RecordCreationEntity oldData = queryService.selectByPk(id);
if (oldData != null && !Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId().equals(oldData.getCreatorId())) {
if (oldData != null &&context.getAuthentication().getUser().getId().equals(oldData.getCreatorId())) {
return false;
}
}
@@ -96,8 +90,8 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
return true;
}
protected boolean doQueryAccess(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context) {
Entity entity = context.getParams()
protected boolean doQueryAccess(OwnCreatedDataAccessConfig access, AuthorizingContext context) {
Entity entity = context.getParamContext().getParams()
.values().stream()
.filter(Entity.class::isInstance)
.map(Entity.class::cast)
@@ -116,11 +110,11 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
queryParamEntity.setTerms(new ArrayList<>());
//添加一个查询条件
queryParamEntity
.where(RecordCreationEntity.creatorId, Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId())
.where(RecordCreationEntity.creatorId,context.getAuthentication().getUser().getId())
//客户端提交的参数 作为嵌套参数
.nest().setTerms(oldParam);
} else if (entity instanceof RecordCreationEntity) {
((RecordCreationEntity) entity).setCreatorId(Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId());
((RecordCreationEntity) entity).setCreatorId(context.getAuthentication().getUser().getId());
} else {
logger.warn("try validate query access,but entity not support, QueryParamEntity and RecordCreationEntity support now!");
}

View File

@@ -8,6 +8,7 @@ import org.hswebframework.web.BusinessException;
import org.hswebframework.web.authorization.access.DataAccessConfig;
import org.hswebframework.web.authorization.access.DataAccessHandler;
import org.hswebframework.web.authorization.access.ScriptDataAccessConfig;
import org.hswebframework.web.authorization.define.AuthorizingContext;
import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
/**
@@ -22,7 +23,7 @@ public class ScriptDataAccessHandler implements DataAccessHandler {
}
@Override
public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
public boolean handle(DataAccessConfig access, AuthorizingContext context) {
ScriptDataAccessConfig dataAccess = ((ScriptDataAccessConfig) access);
DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(dataAccess.getScriptLanguage());
if (engine == null) throw new UnsupportedOperationException(dataAccess.getScriptLanguage() + " {not_support}");
@@ -31,7 +32,7 @@ public class ScriptDataAccessHandler implements DataAccessHandler {
if (!engine.compiled(scriptId)) {
engine.compile(scriptId, dataAccess.getScript());
}
Object success = engine.execute(scriptId, context.getParams()).getIfSuccess();
Object success = engine.execute(scriptId, context.getParamContext().getParams()).getIfSuccess();
return StringUtils.isTrue(success);
} catch (Exception e) {
throw new BusinessException("{script_error}", e);