Service Access Strategy - ABAC Activation Criteria

The ABAC strategy can be modified to conditionally activate the access strategy policy, and then optionally decide the final access strategy result if the strategy is determined to remain inactive.

You can implement the conditions using the following strategies.

  • The activation strategy can be conditionally activated based on available principal attributes.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "https://app.example.org",
      "name" : "Example",
      "accessStrategy" : {
        "@class" : "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
        "requiredAttributes" : {
          "@class" : "java.util.HashMap",
          "cn" : [ "java.util.HashSet", [ "admin" ] ]
        },
        "activationCriteria": {
           "@class": "org.apereo.cas.services.AttributeBasedRegisteredServiceAccessStrategyActivationCriteria",
            "allowIfInactive": false,
            "operator": "AND",
            "requiredAttributes": {
              "@class" : "java.util.HashMap",
              "firstName": [ "java.util.ArrayList", [ "John", "Jon" ] ],
              "lastName": [ "java.util.ArrayList", [ "Holdoor", "Hodor" ] ]
            }
        }
      }
    }
    

    In the above example, the access strategy is only activated if the current principal has a lastName attribute with values Jon or John, AND has a firstName attribute with values Holdoor or Hodor. The operator field can also be modified to use OR.

    Note that if the access strategy fails to activate and must remain inactive, then access is denied via allowIfInactive.

  • You can decide whether the access strategy should be activated using a Groovy script, that may be defined either inline or outsourced to an external Groovy script.

    Below shows the option where you define the Groovy script directly within the body of the service definition:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "https://app.example.org",
      "name" : "Example",
      "accessStrategy" : {
        "@class" : "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
        "requiredAttributes" : {
          "@class" : "java.util.HashMap",
          "cn" : [ "java.util.HashSet", [ "admin" ] ]
        },
        "activationCriteria": {
           "@class": "org.apereo.cas.services.GroovyRegisteredServiceAccessStrategyActivationCriteria",
           "groovyScript": "groovy { return accessRequest.principalId.startsWith('admin-') }",
           "allowIfInactive": true
        }
      }
    }
    

    The accessRequest object allows one to define conditions based on the following attached properties:

    Code Description
    principalId The identifier of the current principal after a successful authentication event.
    attributes A Map of attributes attached to the principal after a successful authentication event.
    service The Service object representing the current application request.
    registeredService The registered service definition in CAS that is mapped to the Service.

    Alternatively, you could also outsource the Groovy script to an external file:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "https://app.example.org",
      "name" : "Example",
      "accessStrategy" : {
        "@class" : "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
        "requiredAttributes" : {
          "@class" : "java.util.HashMap",
          "cn" : [ "java.util.HashSet", [ "admin" ] ]
        },
        "activationCriteria": {
           "@class": "org.apereo.cas.services.GroovyRegisteredServiceAccessStrategyActivationCriteria",
           "groovyScript": "file:///etc/cas/config/AccessStrategy.groovy",
           "allowIfInactive": true
        }
      }
    }
    

    The script itself may be designed as:

    1
    2
    3
    4
    5
    6
    7
    
    import org.apereo.cas.services.*
    
    def run(Object[] args) {
        def (context,logger) = args
        logger.info("Checking ${context.principalId} - ${context.registeredService.name}")
        return true
    }
    
  • You can also combine multiple activation criteria using a chaining setup:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "https://app.example.org",
      "name" : "Example",
      "accessStrategy" : {
        "@class" : "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
        "requiredAttributes" : {
          "@class" : "java.util.HashMap",
          "cn" : [ "java.util.HashSet", [ "admin" ] ]
        },
        "activationCriteria": {
            "@class": "org.apereo.cas.services.ChainingRegisteredServiceAccessStrategyActivationCriteria",
            "conditions": [ "java.util.ArrayList", [
              {
                "@class": "org.apereo.cas.services.AttributeBasedRegisteredServiceAccessStrategyActivationCriteria",
                "order": 1,
                "requiredAttributes": {
                  "@class": "java.util.HashMap",
                  "cn": [ "java.util.ArrayList", [ "name1", "name2" ]]
                }
              },
              {
                "@class": "org.apereo.cas.services.GroovyRegisteredServiceAccessStrategyActivationCriteria",
                "order": 2,
                "groovyScript": "groovy { return accessRequest.principalId.startsWith('admin-') }"
              }
            ]],
            "operator": "AND"
        }
      }
    }