View Javadoc

1   package com.atlassian.asap.core.server.filter;
2   
3   import com.atlassian.asap.api.Jwt;
4   import com.google.common.collect.ImmutableMap;
5   
6   import javax.servlet.http.HttpServletRequest;
7   import java.util.Map;
8   import java.util.Optional;
9   import java.util.function.Predicate;
10  
11  /**
12   * This class accepts a list of issuers and the authentication rules associated with each one.
13   *
14   * <p>Any issuer that is not in the list will be rejected.
15   *
16   * <p>For example, we might have some requirement that the issuer Mallory should only be able to use the subject "Mallory",
17   * whereas the issuer Alice might be able to use the subject "Alice" or "Bob". We might write something like this:
18   *
19   * <pre>{@code
20   *      rules = ImmutableMap.of(
21   *          "Mallory", jwt -> "Mallory".equals(jwt.getClaims().getSubject().orElse("Mallory")),
22   *          "Alice", jwt -> ImmutableSet.of("Alice", "Bob").contains(jwt.getClaims().getSubject().orElse("Alice"))
23   *      );
24   * }</pre>
25   *
26   * <p>This would prevent Mallory from using Alice or Bob as the subject when we don't expect them to. (This particular
27   * example is actually covered better by the {@link IssuerAndSubjectAwareRequestAuthorizationFilter}, which extends this
28   * class.)
29   */
30  public class RulesAwareRequestAuthorizationFilter extends AbstractRequestAuthorizationFilter {
31      private final Map<String, Predicate<Jwt>> issuersAndChecks;
32  
33      public RulesAwareRequestAuthorizationFilter(
34              Map<String, Predicate<Jwt>> issuersAndChecks) {
35          this.issuersAndChecks = ImmutableMap.copyOf(issuersAndChecks);
36      }
37  
38      @Override
39      protected boolean isAuthorized(HttpServletRequest request, Jwt jwt) {
40          String issuer = jwt.getClaims().getIssuer();
41  
42          return Optional.ofNullable(issuersAndChecks.get(issuer))
43                  .map(pred -> pred.test(jwt))
44                  .orElse(false);
45      }
46  }