Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The implementation first checks whether the method is part of the allowed list, if it is, . If it is and the target object is an actual Geode region (passed as a bind parameter to the query), it proceeds to check whether the user has the required privileges to execute queries on that particular region (DATA:READ:regionName). The current approach denies everything and only allows some methods to be executed, this list can not be configured or changed in runtime, it’s hard coded and any addition/deletion requires a new release of the productThe list of currently allowed methods is attached below.

...

      return Method.invoke(“user”)

    }

}

Proposal

Summary

Add a new top-level class, QueryInvocationAuthorizer, having Make the currently internal MethodInvocationAuthorizer interface public and allow users to provide their own, it will hold the entire Method Authorization Implementation and split the current MethodInvocationAuthorizer in two different interfaces, each one having a clear and independent responsibility:

  • RegionInvocationAuthorizer
  • MethodInvocationAuthorizer

The QueryInvocationAuthorizer will use an empty implementation of both interfaces if The QueryService will use an empty implementation of the interface if security is disabled or the flag QueryService.allowUntrustedMethodInvocation is set as true (as it works right now). If security is enabled, the default RegionInvocationAuthorizer will be used, and a default MethodInvocationAuthorizer will be default RestrictedMethodAuthorizer will be set or, if configured, the custom implementation will be used. In runtime, the RegionInvocationAuthorizer will be always invoked first; if it succeeds and the user has privileges to query the region, the configured implementation of MethodInvocationAuthorizer will be executed.

Based on the comments added to the original proposal, the feedback gathered through the Geode dev list within the relevant thread, Based on the comments added to the original proposal and having in mind the current requirements, the following implementations should be provided out of the box:

  • RestrictedMethodAuthorizer
  • RegexBasedMethodAuthorizerDataAwareBasedMethodAuthorizer
  • JavaBeanAccessorBasedMethodAuthorizer

The three of them, by default, will only allow the methods currently allowed by RestrictedMethodInvocationAuthorizer plus The RestrictedMethodAuthorizer will be the authorizer used by default out of the box, as it contains the list of methods per object type that are currently considered safe. The other two authorizers will only permit the methods currently allowed by RestrictedMethodAuthorizer plus whatever the internal implementation is configured to do. The JavaBeanAccessorBasedMethodAuthorizer and DataAwareBasedMethodAuthorizer cover covers the most common use cases and requires little to no configuration effort. For those use cases not covered, the user users can choose to use the RegexBasedMethodAuthorizer, which allows them to configure which methods to allow directly through regex expressions. If none of the above is a good fit for a particular situation, the user ultimately has the option to provide its own implementation of the MethodInvocationAuthorizer interface and do whatever needed in order to allow/deny the execution of particular methods.

...

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameTentativeClassDiagram
simpleViewerfalse
width
diagramWidth1061981
revision611


Class QueryInvocationAuthorizer Interface MethodInvocationAuthorizer (Internal)

Default implementation, it should verify whether the OQL can be executed on a particular region and whether the method is allowed or not by delegating to RegionInvocationAuthorizer and MethodInvocationAuthorizer respectively. 

Interface RegionQueryInvocationAuthorizer (Internal)

The default implementation should just check whether the user can execute queries on the region (DATA:READ:RegionName) and it should be invoked first in the chain (no point in checking a method if the user doesn’t even have read privileges on the region).

public interface RegionQueryInvocationAuthorizer {

  void authorizeRegionAccess(Region region);

}

Interface MethodInvocationAuthorizer (Public)

This interface is intended to be implemented by users wanting a custom authorization mechanism and by out of the box implementations as well. The interface will have only one method and it should throw NotAuthorizedException (non-checked exception) whenever it detects that the user should not be allowed to execute that particular method during the OQL execution.

public interface MethodInvocationAuthorizer  {

  void authorizeMethodInvocation(Method method, Region region) throws NotAuthorizedException;

}

Abstract Class MethodInvocationAuthorizerAdapter (Public)

Utility class that implements MethodInvocationAuthorizer and has the current RestrictedMethodInvocationAuthorizer logic embedded. Applications can use this class (inheritance) as the starting point for providing custom authorizers.

Configuration Options

Create a new QueryEngineConfig element at the CacheConfig level to contain any configuration related to OQL, including the custom MethodInvocationAuthorizer. Even though at the beginning this new configuration element will be used to configure only the MethodInvocationAuthorizer implementation, it’s worth noting that it provides a single configuration point for the whole query engine. This basically means that it can also be used in the future to allow further additions and configuration options, even replacing the current system properties used to configure the QueryService with new child elements and/or attributes.

The resulting XML element would look something like the following (the properties are just examples):

<query-engine>

 <queryVerbose>true</queryVerbose>

 <allowUntrustedMethodInvocation>false</allowUntrustedMethodInvocation>

 <method-authorizer>

   <class-name>test.Authorizer</class-name>

   <parameter name="allowedMethodsDataBaseUrl">

     <string>jdbc:mysql://myHost/allowedMethodsDatabase</string>

   </parameter>

 </method-authorizer>

</query-engine>

This new configuration element and its properties should be stored and retrieved through the cluster configuration service, and must also be modifiable through gfsh commands:

  • alter query-engine --allowUntrustedMethodInvocation=false
  • alter query-engine --method-authorizer=test.Authorizer{'param':'value'}

Out of the Box Implementations

The code below is shown only as an example, the final implementation might differ.

RegexBasedMethodAuthorizer

Methods allowed to be executed should match some regex expression(s) configured by the user, similar to what we currently do today with the PDX ReflectionBasedAutoSerializer. The implementation will have an internal structure containing already compiled Pattern instances and use them to verify the actual method that should be executed by the OQL engine, denying or allowing the execution based on the match result.

@Override

public void authorizeMethodInvocation(Method method, Region region) throws NotAuthorizedException {

 boolean matches = false;

 String methodName = method.getClass().getName() + "." + method.getName();

 Iterator<Pattern> iterator = this.patternsCache.iterator();

 while (iterator.hasNext() && !matches) {

   matches = iterator.next().matcher(methodName).matches();

 }

 throw new NotAuthorizedException(UNAUTHORIZED_STRING + methodName);

}

Advantages

  • Easy to use and configure what to allow/deny.
  • Regular expressions are standard, everyone “should know” how to use them.

Risks / Unknowns / Disadvantages

  • Performance impact?.
  • Customers still need to configure “something” (the regex).
  • Customers need to learn regex expressions, if they don't do already.
  • Operators with little Regex knowledge can accidentally allow everything, depending on which wildcards are used.

DataAwareBasedMethodAuthorizer

Allow the OQL engine to execute any method on any instance that is part of the object hierarchy inserted into the Geode Region. The idea is, basically, to allow everything as long as it has been inserted into the region by an authenticated user. It's the responsibility of the user to train operators and developers to not execute dangerous methods or mutators on their own objects (if any). Some known dangerous methods (like getClass) should be disabled by default, however.

Advantage

  • No extra configuration needed.

  • Extremely flexible, user can execute any method.

  • Solves the general use case: deploy the domain model, start executing OQL and invoking methods without further changes (other than setting this authorizer through configuration).

Risks / Unknowns / Disadvantages

  • How would it work for method invocation chain? (user.getAddress().getZipCode().getId()).

  • How to get extra metadata about the object on which the method will be executed?. With the current implementation is not possible.

  • Java Reflection is already expensive, going up through the object hierarchy to find out whether the object is part of the region or not will definitely and negatively impact performance.

JavaBeanAccessorBasedMethodAuthorizer

Allow the OQL engine to execute any method that follows the design patterns for accessor methods described in the JavaBean specification 1.01; that is, basically, allow any method starting with get or is. For extra security, only methods belonging to classes under certain packages (configured by the user) should be allowed, and some known dangerous methods (like getClass) should be disabled.

@Override

public void authorizeMethodInvocation(Method method, Region region) throws NotAuthorizedException {

 boolean matches = false;

 String methodName = method.getName().toLowerCase();

 String packageName = method.getDeclaringClass().getPackage().getName().toLowerCase();

 if ((methodName.startsWith("get") || methodName.startsWith("is")) && (!methodName.equalsIgnoreCase("getClass"))) {

   Iterator<String> iterator = this.packagesCache.iterator();

   while (iterator.hasNext() && !matches) {

     matches = iterator.next().startsWith(packageName);

   }

 }

 throw new NotAuthorizedException(UNAUTHORIZED_STRING + methodName);

}

Advantages

  • No major changes needed.

  • Solves the general use case: most customers use get*/is* as the name for accessor methods and the configurable package restricts access only to methods from the domain model.

Risks / Unknowns / Disadvantages

  • Performance impact?.

  • Customers need to configure “something” (the package).

  • Some safe accessor methods might not start with get*/is*.

  • Not every method starting with get*/is* (even on the domain model) might be safe to invoke.

Examples

This section contains some examples showing how the feature should work, once it’s implemented, for different use cases. All examples assume that the cluster is already up and running with security enabled and that the current default method authorizer is configured (nothing is allowed). For the sake of simplicity, let’s also assume that the domain model is entirely contained within packages "order.model" and "tickets.model".

Happy Path

# All classes follow the JavaBean specification 1.01 for accessor methods

# Customer deploys the jar and configures the JavaBeanAccessorBasedMethodAuthorizer

$> deploy --jar=/tmp/model-1.0.0.jar

$> alter query-engine --method-authorizer=JavaBeanAccessorBasedMethodAuthorizer{'packages' : 'order.model,tickets.model'}

Change Authorizer in Runtime

# All classes follow the JavaBean specification 1.01 for accessor methods

# Customer deploys the jar and configures the JavaBeanAccessorBasedMethodAuthorizer

$> deploy --jar=/tmp/model-1.0.0.jar

$> alter query-engine --method-authorizer=JavaBeanAccessorBasedMethodAuthorizer{'packages' : 'order.model,tickets.model'}

# Customer realizes that one developer did not follow the specification and multiple "calculateXXXX" methods exist in several classes

# These methods need to be accessed through OQL right away in production, so they configure RegexBasedMethodAuthorizer with the required regex to allow default java bean accessors (get*|is*) + methods starting with "calculate*"

alter query-engine --method-authorizer=RegexBasedMethodAuthorizer{'patterns' : 'model.*(get|is|calculate)'}

# After removing all "calculateXXXX" methods the customer deploys the new model and re-configures the JavaBeanAccessorBasedMethodAuthorizer

deploy --jar=/tmp/model-2.0.0.jar

alter query-engine --method-authorizer=JavaBeanAccessorBasedMethodAuthorizer{'packages' : 'order.model,tickets.model'}

Custom Authorizer with Hot Deploy

# Out of the box implementations are not suitable for the use case

# A method needs to be allowed on certain regions but denied on others

# Customer develops a custom method authorizer that gets the list of allowed methods per region from an external environment variable

public class EnvironmentAwareAuthorizer implements MethodInvocationAuthorizer {

  private final static String METHODS_ALLOWED_PER_REGION_KEY = "myEnvironmentVariable";

  private Map<String, List<String>> acceptList;

  private void parseEnvironment(String variableName) {

    // Parse JSON environment variable and populate internal map.

  }

  public EnvironmentAwareAuthorizer() {

    parseEnvironment(METHODS_ALLOWED_PER_REGION_KEY);

  }

  @Override

  public void authorizeMethodInvocation(Method method, Region region) throws NotAuthorizedException {

    String regionName = region.getName().toLowerCase();

    String methodName = method.getName().toLowerCase();

    List<String> methodsAllowedWithinRegion = acceptList.get(regionName);

    if ((methodsAllowedWithinRegion != null) && (methodsAllowedWithinRegion.contains(methodName))) {

      return;

    }

    throw new NotAuthorizedException(UNAUTHORIZED_STRING + methodName);

  }

}

# Customer packages the custom implementation + data-model, deploys the single JAR file and configures the custom authorizer

$> deploy --jar=/tmp/library-1.0.0.jar

$> alter query-engine --method-authorizer=io.company.EnvironmentAwareAuthorizer

Discarded Options

The following approaches were discarded for several reasons, they’re included here only for historic purposes.

PDXBasedMethodAuthorizer

We can’t invoke actual methods on objects stored as PdxInstance without deserializing them, that’s a fact, BUT we could have a Method Authorization Implementation that automatically trusts all methods invoked on objects that were deserialized from a PdxInstance.

Pros and Cons

  • Easy to implement (+).
  • No major changes needed (+).
  • Not every method on the object might be safe to execute (-).
  • Customer needs to configure PDX AND also deploy the domain model (-).

ConfigurableAcceptListMethodAuthorizer

Keep the Method Authorization Implementation details internal and only provide support to configure the list of allowed methods to the users. The approach basically implies keeping the actual behaviour and RestrictedMethodInvocationAuthorizer implementation, but improving the class to make it "mutable" in terms of configuration so users can add or remove custom methods to the list of allowed methods in runtime. The methods actually allowed should match exactly the ones to be executed by OQL, any difference will result in the method execution to be rejected by the query engine.

Pros and Cons

  • No major changes needed (+).
  • Easy to understand and configure (+).
  • Cumbersome Configuration (-).
    • Becomes a nightmare for huge data models.
    • User needs to add methods to the accepted list one by one, per class.
    • Maintenance complexity when the amount of methods to allow increases.

AnnotationBasedMethodAuthorizer

Add a new annotation to Geode (@Authorized, @OQLMethod, other?) so users can annotate within their domain model which methods are safe to invoke during OQL execution. In order to decide whether the method is allowed or denied, the implementation will need to check whether the method is annotated with the marker annotation or not.

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@interface Authorized {

}

@Override

public void authorizeMethodInvocation(Method method) throws NotAuthorizedException {

 if (!method.isAnnotationPresent(Authorized.class)) {

   throw new NotAuthorizedException(UNAUTHORIZED_STRING + method.getName());

 }

}

Pros and Cons

Public)

This interface is intended to be implemented by users that want a custom authorization mechanism, and by the out of the box implementations as well. The interface will have only one method and it should return a boolean indicating whether the specified method is allowed to be executed on the target object or not. For those situations on which the authorization can not be determined, the non-checked NotAuthorizedException should be thrown.

public interface MethodInvocationAuthorizer  {

  boolean authorize(Method method, Object target) throws NotAuthorizedException;

}

Class RestrictedMethodAuthorizer (Public)

The current RestrictedMethodInvocationAuthorizer implementation logic, but made public so applications can delegate to this class and use it as the starting point for providing custom authorizers.

Configuration Options

Create a new QueryServiceConfig element at the CacheConfig level to contain any configuration related to OQL, including the custom MethodInvocationAuthorizer. Even though at the beginning this new configuration element will be used to configure only the MethodInvocationAuthorizer implementation, it’s worth noting that it provides a single configuration entry point for the whole query engine. This basically means that it can also be used in the future to allow further additions and configuration options, even replacing the current system properties used to configure the QueryService with new child elements and/or attributes.

The resulting XML element would look something like the following (the properties are just examples):

<query-service>

 <queryVerbose>true</queryVerbose>

 <allowUntrustedMethodInvocation>false</allowUntrustedMethodInvocation>

 <method-authorizer>

   <class-name>test.Authorizer</class-name>

   <parameter name="allowedMethodsDataBaseUrl">

     <string>jdbc:mysql://myHost/allowedMethodsDatabase</string>

   </parameter>

 </method-authorizer>

</query-service>


This new configuration element and its properties should be stored and retrieved through the cluster configuration service, and must also be modifiable through gfsh commands:

  • alter query-service --allowUntrustedMethodInvocation=false
  • alter query-service --method-authorizer=test.Authorizer{'param':'value'}

Out of the Box Implementations

The code below is shown only as an example, the final implementation might differ.

RegexBasedMethodAuthorizer

Methods allowed to be executed should match some regex expression(s) configured by the user, similar to what we currently do today with the PDX ReflectionBasedAutoSerializer. The implementation will have an internal structure containing already compiled Pattern instances and use them to verify the actual method that should be executed by the OQL engine, denying or allowing the execution based on the match result. If there is no match, it will delegate the final decision to the RestrictedMethodAuthorizer.


@Override

public boolean authorize(Method method, Object target) throws NotAuthorizedException {

  boolean matches = false;

  String methodName = target.getClass().getName() + "." + method.getName();

  Iterator<Pattern> iterator = this.patternsCache.iterator();


  while (iterator.hasNext() && !matches) {

    matches = iterator.next().matcher(methodName).matches();

  }


  if (!matches) {

    matches = this.restrictedAuthorizer.authorize(method, target);

  }


  return matches;

}


Advantages

  • Easy to use and configure what to allow/deny.
  • Regular expressions are standard, everyone “should know” how to use them.

Risks / Unknowns / Disadvantages

  • Performance impact?.
  • Customers still need to configure “something” (the regex).
  • Customers need to learn regex expressions, if they don't do already.
  • Operators with little Regex knowledge can accidentally allow everything, depending on which wildcards are used.

JavaBeanAccessorBasedMethodAuthorizer

Allow the OQL engine to execute any method that follows the design patterns for accessor methods described in the JavaBean specification 1.01; that is, basically, allow any method starting with get or is. For extra security, only methods belonging to classes under certain packages (configured by the user) should be allowed, and some known dangerous methods (like getClass) should be disabled. If there is no match, it will delegate the final decision to the RestrictedMethodAuthorizer.


@Override

public boolean authorize(Method method, Object target) throws NotAuthorizedException {

  boolean matches = false;

  String methodName = method.getName().toLowerCase();

  String packageName = target.getClass().getPackage().getName().toLowerCase();


  if ((methodName.startsWith("get") || methodName.startsWith("is")) && (!methodName.equalsIgnoreCase("getClass"))) {

    Iterator<String> iterator = this.packagesCache.iterator();

    while (iterator.hasNext() && !matches) {

      matches = iterator.next().startsWith(packageName);

    }

  }


  if (!matches) {

    matches = this.restrictedAuthorizer.authorize(method, target);

  }


  return matches;

}

Advantages

  • No major changes needed.
  • Solves the general use case: most customers use get*/is* as the name for accessor methods and the configurable package restricts access only to methods from the domain model.

Risks / Unknowns / Disadvantages

  • Performance impact?.

  • Customers need to configure “something” (the package).

  • Some safe accessor methods might not start with get*/is*.

  • Not every method starting with get*/is* (even on the domain model) might be safe to invoke.

Examples

This section contains some examples showing how the feature should work, once it’s implemented, for different use cases. All examples assume that the cluster is already up and running with security enabled and that the current default method authorizer is configured (nothing is allowed). For the sake of simplicity, let’s also assume that the domain model is entirely contained within packages "order.model" and "tickets.model".

Happy Path

# All classes follow the JavaBean specification 1.01 for accessor methods

# Customer deploys the jar and configures the JavaBeanAccessorBasedMethodAuthorizer

$> deploy --jar=/tmp/model-1.0.0.jar

$> alter query-service --method-authorizer=JavaBeanAccessorBasedMethodAuthorizer{'packages' : 'order.model,tickets.model'}

Change Authorizer in Runtime

# All classes follow the JavaBean specification 1.01 for accessor methods

# Customer deploys the jar and configures the JavaBeanAccessorBasedMethodAuthorizer

$> deploy --jar=/tmp/model-1.0.0.jar

$> alter query-service --method-authorizer=JavaBeanAccessorBasedMethodAuthorizer{'packages' : 'order.model,tickets.model'}


# Customer realizes that one developer did not follow the specification and multiple "calculateXXXX" methods exist in several classes

# These methods need to be accessed through OQL right away in production, so they configure RegexBasedMethodAuthorizer with the required regex to allow default java bean accessors (get*|is*) + methods starting with "calculate*"

alter query-service --method-authorizer=RegexBasedMethodAuthorizer{'patterns' : 'model.*(get|is|calculate)'}


# After removing all "calculateXXXX" methods the customer deploys the new model and re-configures the JavaBeanAccessorBasedMethodAuthorizer

deploy --jar=/tmp/model-2.0.0.jar

alter query-service --method-authorizer=JavaBeanAccessorBasedMethodAuthorizer{'packages' : 'order.model,tickets.model'}

Custom Authorizer with Hot Deploy

# Out of the box implementations are not suitable for the use case

# A method needs to be allowed or denied based on runtime configuration

# Customer develops a custom method authorizer that gets the list of allowed methods from an external environment variable.

public class EnvironmentAwareAuthorizer implements MethodInvocationAuthorizer {

  private final static String METHODS_ALLOWED = "myEnvironmentVariable";

  private final boolean configured;

  private Map<String, List<String>> acceptList;


  private void parseEnvironment(String variableName) {

    // Parse JSON environment variable and populate internal map.

  }


  public EnvironmentAwareAuthorizer() {

    try {

      parseEnvironment(METHODS_ALLOWED_PER_REGION_KEY);

      configured = true;

    } catch (Exception parseException) {

      configured = false;

    }

  }


  @Override

  public boolean authorize(Method method, Object target) throws NotAuthorizedException {

    if (!configured) {

      throw new NotAuthorizedException("Configuration not loaded.");

    }


    String typeName = target.getName().toLowerCase();

    String methodName = method.getName().toLowerCase();

    List<String> methodsAllowedPerType = acceptList.get(typeName);


    if ((methodsAllowedPerType != null) && (methodsAllowedPerType.contains(methodName))) {

      return true;

    }


    return false;

  }

}



# Customer packages the custom implementation + data-model, deploys the single JAR file and configures the custom authorizer

$> deploy --jar=/tmp/library-1.0.0.jar

$> alter query-service --method-authorizer=io.company.EnvironmentAwareAuthorizer

Discarded Options

The following approaches were discarded for several reasons, they’re included here only for historic purposes.

PDXBasedMethodAuthorizer

We can’t invoke actual methods on objects stored as PdxInstance without deserializing them, that’s a fact, BUT we could have a Method Authorization Implementation that automatically trusts all methods invoked on objects that were deserialized from a PdxInstance.

Pros and Cons

  • Easy to implement (plus).
  • No major changes needed (plus).
  • Not every method on the object might be safe to execute (minus).
  • Customer needs to configure PDX AND also deploy the domain model (minus).

DataAwareBasedMethodAuthorizer

Allow the OQL engine to execute any method on any instance that is part of the object hierarchy inserted into the Geode Region. The idea is, basically, to allow everything as long as it has been inserted into the region by an authenticated user. It's the responsibility of the user to train operators and developers to not execute dangerous methods or mutators on their own objects (if any). Some known dangerous methods (like getClass) should be disabled by default, however.

Pros and Cons

  • No extra configuration needed (plus).

  • Solves the general use case: deploy the domain model, start executing OQL and invoking methods without further changes (other than setting this authorizer through configuration) (plus).

  • How would it work for method invocation chains, like user.getAddress().getZipCode().getId()(minus).

  • How to get extra metadata about the object on which the method will be executed?. With the current implementation is not possible (minus).

  • We could be invoking methods on an object in lots of places in the query tree, is it even possible to always have the region during the authorization?. (minus).
  • Java Reflection is already expensive, going up through the object hierarchy to find out whether the object is part of the region or not will definitely and negatively impact performance (minus).

AnnotationBasedMethodAuthorizer

Add a new annotation to Geode (@Authorized, @OQLMethod, other?) so users can annotate within their domain model which methods are safe to invoke during OQL execution. In order to decide whether the method is allowed or denied, the implementation will need to check whether the method is annotated with the marker annotation or not.

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@interface Authorized {

}


@Override

public boolean authorize(Method method, Object target) throws NotAuthorizedException {

  return (method.isAnnotationPresent(Authorized.class));

}

Pros and Cons

  • Easy to use and implement (plus).
  • Annotations are becoming the standard, developers are comfortable with them (plus).
  • No extra configuration needed: the deployed domain model contains what we need in runtime (plus).
  • The domain model classes must be present on the server’s classpath (minus).
  • An unnecessary level of coupling is added between the user’s code and Geode (minus).
  • Code is not code anymore, there is embedded configuration in the domain model (minus).

ConfigurableAcceptListMethodAuthorizer

Keep the Method Authorization Implementation details internal and only provide support to configure the list of allowed methods to the users. The approach basically implies keeping the actual behaviour and RestrictedMethodInvocationAuthorizer implementation, but improving the class to make it "mutable" in terms of configuration so users can add or remove custom methods to the list of allowed methods in runtime. The methods actually allowed should match exactly the ones to be executed by OQL, any difference will result in the method execution to be rejected by the query engine.

Pros and Cons

  • No major changes needed (plus).
  • Easy to understand and configure (plus).
  • Cumbersome Configuration (minus).
    • Becomes a nightmare for huge data models.
    • User needs to add methods to the accepted list one by one, per class.
    • Maintenance complexity when the amount of methods to allow increases
  • Easy to use and implement (+).
  • Annotations are becoming the standard, developers are comfortable with them (+).
  • No extra configuration needed: the deployed domain model contains what we need in runtime (+).
  • The domain model classes must be present on the server’s classpath (-).
  • An unnecessary level of coupling is added between the user’s code and Geode (-).
  • Code is not code anymore, there is embedded configuration in the domain model (-)
    • .

ResourcePermissionBasedMethodAuthorizer

...

Pros and Cons

  • Easy to implement (+) (plus).
  • No extra configuration or changes needed (+) (plus).
  • Addition of new resource permission DATA:QUERY:RegionName (-) (minus).
  • Confusing. Multiple roles are required for “the same” OQL execution operation (-) (minus).