Versions Compared

Key

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

...

Code Block
languagejava
firstline144
titleclients/src/main/java/org/apache/kafka/server/authorizer/Authorizer.java
linenumberstrue
    /**
     * Check if the caller is authorized to perform the given ACL operation on at least one
     * resource of the given type.
     *
     * @param1. requestContextFilter Requestout contextall includingthe requestresource resourceType,pattern securitycorresponding protocol,to andthe listenerrequestContext, nameAclOperation,
     * @param op  and ResourceType
     * 2. If wildcard deny Theexists, ACLreturn operationdeny to checkdirectly
     * @param3. resourceTypeFor any literal Theallowed resource, type
if there's no dominant literal *denied @returnresource, and
     *    no dominant prefixed denied resource, Returnreturn {@linkallow
 AuthorizationResult#ALLOWED} if the caller is* authorized4. toFor performany the
prefixed allowed resource, if there's *no dominant denied resource, return allow
     * 5. For any other cases, return deny
     *
   given   ACL* operationIt onis atimportant leastto oneoverride resourcethis ofinterface thedefault givenin type.implementations because
     * 1. The interface default iterates all AclBindings multiple times, without any indexing,
     *    which is Returna {@linkCPU AuthorizationResult#DENIED}intense otherwisework.
     */
 2. The interface default rebuild several AuthorizationResultsets authorizeByResourceType(AuthorizableRequestContextof requestContextstrings, 
													which is a memory intense work.
     AclOperation*
 op, 
														ResourceType resourceType) {
        if (resourceType == ResourceType.ANY) {    * @param requestContext Request context including request resourceType, security protocol, and listener name
     * @param op     throw new IllegalArgumentException(
      The ACL operation to check
     * "Must@param resourceType specify a non-filterThe resource type for authorizeByResourceType");to check
     * @return  }

        if (resourceType == ResourceType.UNKNOWN) {
 Return {@link AuthorizationResult#ALLOWED} if the caller is authorized to perform the
 throw new IllegalArgumentException(
  *              "Unknown resource type");
       given ACL }

operation on at least one resource of the if (op == AclOperation.ANY) {given type.
     *       throw new IllegalArgumentException(
              Return {@link "Must specify a non-filter operation type for authorizeByResourceType");AuthorizationResult#DENIED} otherwise.
     */
    default AuthorizationResult authorizeByResourceType(AuthorizableRequestContext requestContext, AclOperation op, ResourceType resourceType) }{

        if SecurityUtils.authorizeByResourceTypeCheckArgs(op == AclOperation.UNKNOWN) {, resourceType);

        ResourcePatternFilter resourceTypeFilter  = throw new IllegalArgumentExceptionResourcePatternFilter(
            resourceType,    "Unknown operation type"null, PatternType.ANY);
        }

        ResourcePatternFilter resourceTypeFilterAclBindingFilter aclFilter = new ResourcePatternFilterAclBindingFilter(
            resourceTyperesourceTypeFilter, null, PatternTypeAccessControlEntryFilter.ANY);

        AclBindingFilter aclFilterEnumMap<PatternType, Set<String>> denyPatterns =
   new AclBindingFilter(
            resourceTypeFilternew EnumMap<PatternType, AccessControlEntryFilterSet<String>>(PatternType.ANYclass);
{{
        Set<String> denyLiterals = new HashSet<>();
        Set<String> denyPrefixes = put(PatternType.LITERAL, new HashSet<>());
          Set<String> allowLiterals = put(PatternType.PREFIXED, new HashSet<>());
        Set<String>}};
 allowPrefixes = new HashSet<>();
    EnumMap<PatternType, Set<String>> allowPatterns =
 boolean hasWildCardAllow = false;

        for (AclBinding binding : acls(aclFilter))  new EnumMap<PatternType, Set<String>>(PatternType.class){{
            if put(!binding.entryPatternType.LITERAL, new HashSet<>().host().equals(requestContext.clientAddress().getHostAddress()));
            put(PatternType.PREFIXED,        && !binding.entry().host().equals("*"))
                continue;

            if (!binding.entry().principal().equals(requestContext.principal().toString())
                    && !binding.entry().principal().equals("User:*"))
new HashSet<>());
        }};

        boolean hasWildCardAllow = continuefalse;

        KafkaPrincipal principal = new if (binding.entry().operation() != op
KafkaPrincipal(
            requestContext.principal().getPrincipalType(),
           && bindingrequestContext.entryprincipal().operationgetName() != AclOperation.ALL);
        String hostAddr       continue= requestContext.clientAddress().getHostAddress();

        for (AclBinding binding : if (binding.entry().permissionType() == AclPermissionType.DENY) {
acls(aclFilter)) {
            if (!binding.entry().host().equals(hostAddr)    switch (binding.pattern&& !binding.entry().host().patternTypeequals("*"))
  {
              continue;

       case  LITERAL:
   if (!SecurityUtils.parseKafkaPrincipal(binding.entry().principal()).equals(principal)
                    if&& (!binding.patternentry().nameprincipal().equals(ResourcePattern.WILDCARD_RESOURCE"User:*"))
                continue;

            return AuthorizationResult.DENIED;
  if (binding.entry().operation() != op
                          denyLiterals.add(&& binding.patternentry().nameoperation() != AclOperation.ALL);
                continue;

        break;
    if (binding.entry().permissionType() == AclPermissionType.DENY) {
            case PREFIXED:
   switch   (binding.pattern().patternType()) {
                  denyPrefixes.add(binding.pattern().name());
  case LITERAL:
                     break;
   if (binding.pattern().name().equals(ResourcePattern.WILDCARD_RESOURCE))
            }
                return continueAuthorizationResult.DENIED;
            }

            if (binding.entry().permissionType() != AclPermissionType.ALLOW)denyPatterns.get(PatternType.LITERAL).add(binding.pattern().name());
                continue;

        break;
    switch (binding.pattern().patternType()) {
                case LITERALPREFIXED:
                    if (    denyPatterns.get(PatternType.PREFIXED).add(binding.pattern().name().equals(ResourcePattern.WILDCARD_RESOURCE)) {
));
                        break;
       hasWildCardAllow = true;
           default:
             continue;   }
                continue;
    }
        }

            allowLiterals.addif (binding.patternentry().namepermissionType() != AclPermissionType.ALLOW);
                continue;

            switch   break;(binding.pattern().patternType()) {
                case PREFIXEDLITERAL:
                    if allowPrefixes.add(binding.pattern().name());
.equals(ResourcePattern.WILDCARD_RESOURCE)) {
                      break  hasWildCardAllow = true;
            }
        }

    continue;
    if  (hasWildCardAllow) {
            return AuthorizationResult.ALLOWED;
}
           }

        for (String allowPrefix : allowPrefixes) {
allowPatterns.get(PatternType.LITERAL).add(binding.pattern().name());
                StringBuilder sb = new StringBuilder()break;
               boolean hasDominatedDeny = false;
 case PREFIXED:
                for (char ch : allowPrefix.toCharArray allowPatterns.get(PatternType.PREFIXED).add(binding.pattern().name()) {
;
                    sb.append(ch)break;
                if (denyPrefixes.contains(sb.toString())) {default:
            }
        hasDominatedDeny}

 = true;
      if (hasWildCardAllow) {
            breakreturn AuthorizationResult.ALLOWED;
        }

        }
        for (Map.Entry<PatternType, Set<String>> entry : allowPatterns.entrySet()) {
    }
        for (String allowStr : if (!hasDominatedDeny)entry.getValue()) {
                returnif AuthorizationResult.ALLOWED;
        }
(entry.getKey() == PatternType.LITERAL
        for (String allowLiteral : allowLiterals) {
            if (denyLiterals&& denyPatterns.get(PatternType.LITERAL).contains(allowLiteralallowStr))
                    continue;
                StringBuilder sb = new StringBuilder();
                boolean hasDominatedDeny = false;
                for (char ch : allowLiteralallowStr.toCharArray()) {
                    sb.append(ch);
                    if (denyPrefixesdenyPatterns.get(PatternType.PREFIXED).contains(sb.toString())) {
                        hasDominatedDeny = true;
                        break;
                    }
                }
                if (!hasDominatedDeny)
                    return AuthorizationResult.ALLOWED;
            }
        }

        return AuthorizationResult.DENIED;
    }

...