Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Since the current OFBiz security implementation uses indirect security control, there is no direct connection of permission logic to the artifact that the logic is trying to control access to. Access to a particular artifact could be (and often is) controlled by a handful of different scripts. While this may appear to be an advantage (because it's flexible), it becomes a problem when something about the artifact changes that requires a change in access control. Permission scripts that control the artifact must be tracked down and updated.

Permission checking is optional. Through oversight or laziness artifacts can be left unprotected - opening up security holes or attack vectors.

The coarse grained permission logic fosters an "all or nothing" design mentality. Smaller artifacts - like menu items and data entry fields - can be controlled individually by permissions, but it requires cumbersome conditional code. Many times the developer will just give the user access to all of these smaller artifacts - regardless of whether or not the user has permission to use them.

...

If each artifact has its own set of permissions, there could be potentially thousands of permissions - an administration nightmare! It would be helpful to have artifact permissions organized in a hierarchy - so that permissions defined higher up in the hierarchy are inherited by artifacts lower in the hierarchy. The hierarchy will reduce the number of permissions needed.

Note

The following hierarchy has been called a "static hierarchy" and it is not finalized. There is an alternative to it called "dynamic hierarchy" - see below.

The components in OFBiz are organized in a hierarchy, and each component typically contains entities, services, and screen widgets. We can build on that structure to set up a hierarchy of security-aware artifacts:

...

An execution path could be considered a hierarchy. We can build on that structure to set up a hierarchy of security-aware artifacts:

  • OFBiz
    • Component
      • WebApp
        • ControllerRequest
          • ControllerRequestEvent
            • Service
              • Entity
                • EntityField
        • ControllerView
          • WidgetScreen
            • Service
              • Entity
                • EntityField
            • FtlFile
              • WidgetScreen
            • WidgetForm
              • WidgetFormField

...

  • Budget
  • BudgetAttribute
  • ...
  • PartyRate

...

  • createPartyAcctgPreference
  • updatePartyAcctgPreference
  • ...
  • payflowCCRefund

...

    • ...

Permissions assigned at the OFBiz/applicationscomponent/accounting webapp level are inherited by all artifacts below that level. Permissions assigned at lower levels replace any inherited permissions. Permission inheritance is managed by the authorization manager.

In the design overview, it was mentioned that the security-aware artifact provides its identifier to the authorization manager when requesting permissions for itself. That identifier must be unique in order for the system to work. We can leverage the artifact hierarchy to construct a unique artifact identifier. The Budget entity's identifier would be OFBiz/applications/accounting/entity/Budget. The FindAgreement screen's identifier would be OFBiz/applications/accounting/screen/FindAgreement. The authorization manager should handle the identifier in a case-insensitive way.

The "OFBiz" portion of the identifier is considered the root of the hierarchy. The "applications" and "framework" portions of the identifiers could be left out of the design.

The permission list returned by the authorization manager is The permission list returned by the authorization manager is a set of flags - implemented as key/value pairs. The flag key indicates the type of permission - view, create, update, delete, etc. Valid flag values are "true" or "false." A value of "true" indicates access-granted, and a value of "false" or the absence of a key/value pair indicates access-denied. The permission list could consist of the standard view, create, update, and delete permissions. Artifacts are allowed to define additional permissions. For example, a web application or service artifact might need only one permission - access.

...

Handling permissions with reused artifacts is greatly simplified with the Security-Aware Artifacts design. The problems associated with the existing intermediary design plus coarse-grained hard-coded permissions are eliminated.

When a screen widget artifact is reused in another component, that artifact's identifier changes - since its execution path is different. For example, if I reuse the Example component's EditExample screen in my specialpurpose/NewApplication component (by including it in my own screen definition), the reused EditExample screen artifact identifier changes from OFBiz/framework/example/screen/EditExample to OFBiz/specialpurpose/NewApplication/screen/EditExample. Permissions assigned to the latter will not grant access to the former.

The form in the reused EditExample screen will generate an updateExample event which, in turn, invokes the updateExample service. Just like the EditExample screen, the updateExample service artifact's identifier changes - I can give the users of NewApplication permission to access OFBiz/frameworkNewApplication/exampleupdateExample/service/updateExample without giving them access to any other Example component artifacts.

Not all artifact reuse will be this simple. But the more complicated scenarios can be accommodated by finding ways to "graft" the reused artifact into the new component's artifact hierarchy - which will provide a means to assign permissions to the reused artifact.

Transition

Transition

The existing security design The existing security design and the new Security-Aware Artifact design can coexist. This ability will ease the transition to the new design.

...

The result of each artifact access control check will include:

  • authTypeEnumId (NotSpecified, Allow, Deny, AlwaysAllow (overrides Deny))
  • inheritSubArtifactAuth (Y, N)

Whenever an artifact is hit the authorization (access control) will be checked and the results of it will be kept in the artifactAccessStack. In order to support the inheritParentArtifactAuth field, as part of the ExecutionContext we will maintain a parentAuthorizationState variable that keeps track of the authTypeEnumId of the last artifact that had inheritParentArtifactAuth=Y. If an artifact called by the parent artifact passed but does not have inheritParentArtifactAuth=Y then the parentAuthorizationState variable will not be changed.

Note

David, I don't think the ExecutionContext object should be concerned with security or the permissions hierarchy - that is the Authorization Manager's responsibility. All the ExecutionContext needs to provide is an artifact ID that the artifact can pass on to the Authorization Manager. -Adrian

The reason for this is that depending on the parentAuthorizationState The reason for this is that depending on the parentAuthorizationState the permission still needs to be checked but the results are interpreted differently:

  • if parentAuthorizationState=NotSpecified:
    • authTypeEnumId interpreted as-is
  • if parentAuthorizationState=Allow:
    • authTypeEnumId=NotSpecified: auth passed
    • authTypeEnumId=Allow: auth passed
    • authTypeEnumId=Deny: auth failed
    • authTypeEnumId=AlwaysAllow: auth passed
  • if parentAuthorizationState=AlwaysAllow:
    • authTypeEnumId=NotSpecified: auth passed
    • authTypeEnumId=Allow: auth passed
    • authTypeEnumId=Deny: auth passed
    • authTypeEnumId=AlwaysAllow: auth passed

Note that parentAuthorizationState will never be set to "Deny" because before that would happen the auth would have failed and an error sent back up the stack.

Note

The following hierarchy has been called a "dynamic hierarchy" and it is not finalized. There is an alternative to it called "static hierarchy" - mentioned above.

Example Chain:

  • Component
    • WebApp
      • ControllerRequest
        • ControllerRequestEvent
          • Service
            • Entity
              • EntityField
      • ControllerView
        • WidgetScreen
          • Service
            • Entity
              • EntityField
          • FtlFile
            • WidgetScreen
          • WidgetForm
            • WidgetFormField

Authorization Manager Implementation

...

Execution Context Implementation

Details can be found here.

Authorization Manager Implementation

The existing security classes will be refactored so the Security abstract class is converted to an interface, and the OFBizSecurity class will implement the interface. The Authorization Manager methods will be added to the Security interface, and the existing methods will be deprecated. This will make the conversion backward-compatible with existing installations. Details

Info

The security classes have been refactored and committed. The Authorization Manager methods will be a separate interface, and the Security interface will extend it.

...

Access Control Scenarios

1. User X can use Artifact Y for anything that artifact supports and on any data (where "artifact" is a screen, web page, part of a screen or page, service, general logic, etc). Details

...