`
liyixing1
  • 浏览: 959266 次
  • 性别: Icon_minigender_1
  • 来自: 江西上饶
社区版块
存档分类
最新评论

ofbiz中各类安全代码解析

 
阅读更多
security.hasPermission方法

public boolean hasPermission(String permission, GenericValue userLogin) {
        if (userLogin == null) return false;
//查找出用户对应的安全组
        Iterator<GenericValue> iterator = findUserLoginSecurityGroupByUserLoginId(userLogin.getString("userLoginId"));
        GenericValue userLoginSecurityGroup = null;

//遍历每个组,查看是否这个组拥有这个权限
        while (iterator.hasNext()) {
            userLoginSecurityGroup = iterator.next();
            if (securityGroupPermissionExists(userLoginSecurityGroup.getString("groupId"), permission)) return true;
        }

        return false;
    }


而对于查找用户对应的组则很简单
collection = delegator.findByAnd("UserLoginSecurityGroup", UtilMisc.toMap("userLoginId", userLoginId), null);
查找表UserLoginSecurityGroup中userLoginid的信息
,再通过
collection = EntityUtil.filterByDate(collection, true);
过滤掉已经能够过期的组


securityGroupPermissionExists
方法也比较简单,是
从SecurityGroupPermission表读出一条permissionId=我们需要检查的权限groupId是当前组的id,如果结果不是null,就是存在这个权限了。

服务的授权代码
在ServiceDispatcher中(10.4版本代码,443行)代码
context = checkAuth(localName, context, modelService);
这是检查的代码,进入代码查看
,这里删除了一部分代码
private Map<String, Object> checkAuth(String localName,
Map<String, Object> context, ModelService origService)
throws ServiceAuthException, GenericServiceException {
DispatchContext dctx = this.getLocalContext(localName);
//这是处理service中的<permission-service service-name=""/>元素的。它会负责调用这个service,这个service需要返回一个Boolean hasPermission,来决定是否权限通过。
if (UtilValidate.isNotEmpty(origService.permissionServiceName)) {
Map<String, Object> permResp = origService.evalPermission(dctx,
context);
Boolean hasPermission = (Boolean) permResp.get("hasPermission");
if (hasPermission == null) {
throw new ServiceAuthException(
"ERROR: the permission-service ["
+ origService.permissionServiceName
+ "] did not return a result. Not running the service ["
+ origService.name + "]");
}
if (hasPermission.booleanValue()) {
context.putAll(permResp);
context = origService.makeValid(context, ModelService.IN_PARAM);
} else {
//很明显,未通过,赏它一段未通过的信息。
String message = (String) permResp.get("failMessage");
if (UtilValidate.isEmpty(message)) {
message = ServiceUtil.getErrorMessage(permResp);
}
if (UtilValidate.isEmpty(message)) {
message = "You do not have permission to invoke the service ["
+ origService.name + "]";
}
throw new ServiceAuthException(message);
}
} else {
//事件的权限处理origService.evalPermissions,进去look。
if (!origService.evalPermissions(dctx, context)) {
Locale l = (Locale) context.get("locale");
throw new ServiceAuthException(UtilProperties.getMessage(
"ServiceError", "Service.Auth", l)
+ "[" + origService.name + "]");
}
}

return context;
}


//没的神马东西,看来还得往里进,这里只要知道permissionGroups里面的是要检查的所有的权限内容。

<required-permissions join-type="AND">
<check-permission permission="TEST_VIEW" />
</required-permissions>
那么只有一个required-permissions,那permissionGroups只有一个对象(size=1)
public boolean evalPermissions(DispatchContext dctx, Map<String, ? extends Object> context) {
        // old permission checking
        if (this.containsPermissions()) {
            for (ModelPermGroup group: this.permissionGroups) {
                if (!group.evalPermissions(dctx, context)) {
                    return false;
                }
            }
            return true;
        } else {
            return true;
        }
    }


//进入group.evalPermissions(dctx, context)方法

public boolean evalPermissions(DispatchContext dctx, Map<String, ? extends Object> context) {
//这里的permissions就是required-permission中的check-permission之类的子元素,类型是org.ofbiz.service.ModelPermission
        if (UtilValidate.isNotEmpty(permissions))  {
            boolean foundOne = false;
            for (ModelPermission perm: permissions) {
//这里还要再调用evalPermission来处理权限
                if (perm.evalPermission(dctx, context)) {
                    foundOne = true;
                } else {
                    if (joinType.equals(PERM_JOIN_AND)) {
                        return false;
                    }
                }
            }
            return foundOne;
        } else {
            return true;
        }
    }

//继续进入evalPermission
public boolean evalPermission(DispatchContext dctx, Map<String, ? extends Object> context) {
        GenericValue userLogin = (GenericValue) context.get("userLogin");
        Authorization authz = dctx.getAuthorization();
        Security security = dctx.getSecurity();
//没登陆,肯定直接pass了。
        if (userLogin == null) {
            Debug.logInfo("Secure service requested with no userLogin object", module);
            return false;
        }

//有类型的,PERMISSION,简单的类型
        switch (permissionType) {
            case PERMISSION:
                return evalAuthzPermission(authz, userLogin, context);
ENTITY_PERMISSION是permission+action的类型
            case ENTITY_PERMISSION:
                return evalEntityPermission(security, userLogin);
ROLE_MEMBER角色检查
            case ROLE_MEMBER:
                return evalRoleMember(userLogin);
PERMISSION_SERVICE使用服务方式处理的权限类型。,在required-permissions自然也可以包含permission-service
            case PERMISSION_SERVICE:
                return evalPermissionService(serviceModel, dctx, context);
            default:
                Debug.logWarning("Invalid permission type [" + permissionType + "] for permission named : " + nameOrRole + " on service : " + serviceModel.name, module);

简单的处理方式
private boolean evalAuthzPermission(Authorization authz, GenericValue userLogin, Map<String, ? extends Object> context) {
        if (nameOrRole == null) {
            Debug.logWarning("Null permission name passed for evaluation", module);
            return false;
        }
//authz是Authorization类,也没有必要再看下去了,这里是查找出这个用户当前所有的组,再看组里面有没有这个权限。
        return authz.hasPermission(userLogin.getString("userLoginId"), nameOrRole, context);


    }

                return false;
        }
    }

再看ENTITY_PERMISSION类型的权限检查
它是调用
private boolean evalEntityPermission(Security security, GenericValue userLogin) {
        if (nameOrRole == null) {
            Debug.logWarning("Null permission name passed for evaluation", module);
            return false;
        }
        if (action == null) {
            Debug.logWarning("Null action passed for evaluation",  module);
        }
        return security.hasEntityPermission(nameOrRole, action, userLogin);
    }
实际上是通过Security 的hasEntityPermission方法类处理。
再其内部实际上可以看到的是(entity就是<check-permission permission="TEST_VIEW" />中的permission)
// always try _ADMIN first so that it will cache first, keeping the cache smaller
            if (securityGroupPermissionExists(userLoginSecurityGroup.getString("groupId"), entity + "_ADMIN"))
                return true;
            if (securityGroupPermissionExists(userLoginSecurityGroup.getString("groupId"), entity + action))
                return true;
它会对permission+action何permission+_ADMIN两者一起进行处理。


ROLE_MEMBER
evalEntityPermission方法,具体内容暂时不看了。
分享到:
评论

相关推荐

    Ofbiz框架中的事务解析.pdf

    在理解Ofbiz中的事务处理之前,我们先要回顾一下Java中的事务概念。 Java的事务分为本地事务和全局事务。本地事务是通过设置JDBC连接的`setAutoCommit(false)`来手动开启的,所有在这个连接上的操作都将被包含在一...

    ofbiz框架(文档)全

    在OFBiz中,过滤器用于在请求到达实际处理业务的组件之前进行安全检查、数据验证等操作。 2. **控制器(Controller)**:在OFBiz中,控制器负责调度请求,根据配置文件中的映射规则将请求路由到相应的处理器。...

    ofbiz中文技术文档

    2. **架构概述**:Ofbiz基于Service Engine、Entity Engine、Event Engine、WorkEffort Engine等核心引擎,文档可能会解析这些组件的作用及其相互关系,帮助读者理解Ofbiz的设计理念。 3. **模块详解**:Ofbiz包含...

    ofbiz源代码,库

    刚一近公司就让我用ofbiz做项目,ofbiz中文版+中文文档,liferay中文版+中文文档

    ofbiz-minilang解析示例

    下面是一个Ofbiz-minilang解析示例,展示了minilang中的一些常用标签和用法。 Login-required Login-required是一个特殊的标签,用于指定当前用户是否需要登录验证。如果当前用户未登录,将被重定向到登录页面。该...

    ofbiz安装与配置

    1. SVN 插件安装:我们需要在 Eclipse 中安装 SVN 插件,以便从 SVN 仓库中下载 Ofbiz 的源代码。我们可以在 Eclipse 的“Help”菜单中选择“Install New Software...”,然后输入 Subclipse 安装地址:...

    ofbiz中文文档.doc

    过滤器在OFBiz中的一个重要角色是上下文安全过滤器(Context Security Filter),它确保了请求的安全性,防止未授权的访问。通过这种方式,OFBiz实现了业务逻辑与表示层的彻底分离,提高了系统的灵活性和可维护性。 ...

    ofbiz学习笔记(自学整理)

    服务是Ofbiz中执行特定任务的可重用代码单元,可以通过XML定义并调用。实体则代表业务对象,如产品、订单和客户,它们的定义存储在数据库模型中,并通过实体引擎进行操作。 在Ofbiz中,工作流系统允许定义和自动化...

    ofbiz权限(全)

    在OFBiz权限管理系统中,采用了“安全组”(SecurityGroup)的概念来关联“权限”与“用户”。系统中的权限种类繁多,包括但不限于系统预设权限、用户自定义权限、资源权限、操作权限等。这些权限与安全组之间建立多...

    Ofbiz 数据库全模型

    在Ofbiz中,数据库模型扮演着至关重要的角色,它是系统数据结构的基础,定义了所有业务实体及其相互关系。 数据库模型是Ofbiz的核心组成部分,它描述了系统中的各种实体(如产品、订单、客户等)以及它们之间的关系...

    ofbiz综合使用手册

    在ofbiz中,模型通常是业务逻辑的事件和服务,它们处理数据并响应变化。 - **视图(View)**:展示模型的数据,提供用户界面。一个模型可以对应多个视图,视图也可以与不同模型关联,以实现多角度展示数据。视图还负责...

    Apache.OFBiz.Development

    6. 编译OFBiz和加载数据:在安装OFBiz之后需要编译代码,加载数据以确保OFBiz的正常运行。 7. OFBiz启动与监控:涉及到启动OFBiz应用,包括内存分配、运行状态监控和日志查看。也包括了可能遇到的启动问题及其解决...

    关于OFBIZ的资料

    5. **文档资料**:除了代码和演示数据,压缩包可能还包含OfBiz的官方文档,包括用户手册、开发者指南和技术参考,这些都是学习OfBiz的重要资源。 6. **源码分析**:对于开发人员而言,理解OfBiz的源码结构和设计...

    ofbiz 数据模型 中文手册

    在使用手册时,读者需要注意文档可能存在的OCR扫描错误,并且在实际应用中,应当结合OFBiz官方文档以及源代码来完整理解数据模型的设计意图,因为手册可能并不包含所有的细节,比如索引、触发器、存储过程以及数据...

    ofbiz数据结构设计

    在OFBiz中,实体代表业务对象,如产品、订单、顾客等。每个实体由一组属性组成,这些属性描述了实体的特征。实体间通过关系相互关联,如一个订单可以包含多个产品,这在数据结构中体现为订单实体和产品实体之间的多...

    Apache OFBiz Cookbook

    ### Apache OFBiz Cookbook 知识点解析 #### 一、Apache OFBiz 概述 - **定义**:Apache OFBiz(Open For Business)是一款开源的企业级应用框架,它集成了ERP(企业资源规划)、CRM(客户关系管理)以及E-...

    ofbiz api开发文档

    - **服务**:描述了OFBiz中的服务接口,如订单处理、库存管理等。 - **组件**:OFBiz由多个组件组成,如产品、订单、客户服务等,每个组件都有一系列的API接口。 - **实体**:OFBiz的实体模型是其数据存储的基础...

    解决ofbiz中文报表"#"导入字体

    ofbiz后台应用 - 订单 - 订单查询/订单列表 - 订单明细 - "PDF" 报表, 中文报"#" 错误。 需导入中文解决

Global site tag (gtag.js) - Google Analytics