Attribute Release Policy - Activation Criteria

Almost all attribute release policies can be modified to conditionally activate the release policy. This allows the release policy to dynamically decide whether attributes should be released at all to the target application.

You can implement the conditions using the following strategies.

  • The release policy 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
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "https://app.example.org",
      "name" : "Example",
      "attributeReleasePolicy" : {
        "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy",
        "allowedAttributes" : [ "java.util.ArrayList", [ "cn", "mail", "sn" ] ],
        "activationCriteria": {
            "@class": "org.apereo.cas.services.AttributeBasedRegisteredServiceAttributeReleaseActivationCriteria",
            "operator": "AND",
            "reverseMatch": false,
            "requiredAttributes": {
              "@class" : "java.util.HashMap",
              "firstName": [ "java.util.ArrayList", [ "John", "Jon" ] ],
              "lastName": [ "java.util.ArrayList", [ "Holdoor", "Hodor" ] ]
            }
        }
      }
    }
    

    In the above example, the attribute release policy 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.

    The reverseMatch field can be used to invert the logic of the condition. When set to true,
    principal must not carry any of the required attributes for the policy to activate.

  • The release policy can be conditionally activated via a Groovy script, that may be defined either inline or outsourced to an external Groovy script.

    Below shows the option where you define an external Groovy script:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "...",
      "name" : "...",
      "id" : 1,
      "attributeReleasePolicy" : {
        "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy",
        "allowedAttributes" : [ "java.util.ArrayList", [ "cn", "mail", "sn" ] ],
        "activationCriteria": {
            "@class":"org.apereo.cas.services.GroovyRegisteredServiceAttributeReleaseActivationCriteria",
            "groovyScript" : "file:///path/to/script.groovy"
        }
      }
    }
    

    The script itself may be designed as:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    def run(Object[] args) {
        def (context,logger) = args
        def principal = context.principal
        logger.info("Principal id is ${principal.id}, service is ${context.service}")
        if (principal.id == 'Gandalf') {
            logger.info("User is too powerful; Releasing attributes is allowed")
            return true
        }
        return false
    }
    

    The following parameters are passed to the script:

    Parameter Description
    context The object that carries the attribute release execution context.
    logger The object responsible for issuing log messages such as logger.info(...).

    You may also do the same sort of thing with an inline Groovy script:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "...",
      "name" : "...",
      "id" : 1,
      "attributeReleasePolicy" : {
        "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy",
        "allowedAttributes" : [ "java.util.ArrayList", [ "cn", "mail", "sn" ] ],
        "activationCriteria": {
            "@class":"org.apereo.cas.services.GroovyRegisteredServiceAttributeReleaseActivationCriteria",
            "groovyScript" : "groovy { context.principal.id == 'Gandalf' }"
        }
      }
    }
    
  • 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
    
    {
      "@class" : "org.apereo.cas.services.CasRegisteredService",
      "serviceId" : "...",
      "name" : "...",
      "id" : 1,
      "attributeReleasePolicy" : {
        "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy",
        "allowedAttributes" : [ "java.util.ArrayList", [ "cn", "mail", "sn" ] ],
        "activationCriteria": {
            "@class":"org.apereo.cas.services.ChainingRegisteredServiceAttributeReleaseActivationCriteria",
            "conditions": [ "java.util.ArrayList", [
                {
                    "@class": "org.apereo.cas.services.AttributeBasedRegisteredServiceAttributeReleaseActivationCriteria",
                    "operator": "AND",
                    "requiredAttributes": {
                      "@class": "java.util.HashMap",
                      "cn": [ "java.util.ArrayList", [ "confidential" ] ]
                    }
                },
                {
                    "@class": "org.apereo.cas.services.GroovyRegisteredServiceAttributeReleaseActivationCriteria",
                    "groovyScript": "groovy { return ... }"
                }
            ]],
            "operator": "AND"
        }
      }
    }