1 package com.atlassian.asap.service.api;
2
3 import com.atlassian.asap.api.Jwt;
4 import com.atlassian.asap.service.api.TokenValidator.Policy;
5
6 import java.util.Optional;
7
8 /**
9 * The result from evaluating an {@code Authorization} header against a {@link TokenValidator}.
10 *
11 * @since 2.8
12 */
13 public interface ValidationResult {
14 /**
15 * The overall decision as to whether or not the {@code Authorization} header has satisfied the
16 * validator's requirements.
17 *
18 * @return the decision as to whether or not the request is authorized
19 */
20 Decision decision();
21
22 /**
23 * The token, if any, that was used to authorize this request.
24 * <p>
25 * Note: The value will only be present when {@link #decision()} is {@link Decision#AUTHORIZED}.
26 * </p>
27 *
28 * @return the token, if any, that was used to satisfy the authorization requirements
29 */
30 Optional<Jwt> token();
31
32 /**
33 * The issuer, if any, that provided a token to the request.
34 * <p>
35 * <strong>WARNING</strong>: This is the issuer that the token claimed to be from, but since the token
36 * has been rejected, this information <strong>MUST NOT</strong> be trusted. It is provided for
37 * information / logging purposes, only.
38 * </p>
39 *
40 * @return the issuer, if any, that an untrusted token claimed as its issuer
41 */
42 Optional<String> untrustedIssuer();
43
44
45 /**
46 * The overall decision as to whether or not the request has satisfied the validator's requirements.
47 * <p>
48 * <strong>Usage Note</strong>
49 * </p>
50 * <p>
51 * The names used for the {@code Decision} values and their documentation reflect the standard use of the
52 * terms "authentication" and "authorization" in the security industry. Specifically, "authentication" is
53 * about <strong>identification</strong> (proving who you are) and "authorization" is about
54 * <strong>permission</strong> (associating who you are with what you are allowed to do).
55 * </p><p>
56 * In the early days of HTTP, "authentication" and "authorization" were largely synonymous because the access
57 * controls were so simple that no distinction existed between these two concepts. An HTML page was
58 * restricted with a username and password, and if you were able to successfully authenticate, then that
59 * implicitly meant that you were authorized to access its content. Through this unfortunate accident of
60 * history, the HTTP protocol calls the {@code 401} status {@code "Unauthorized"}. Semantically, however, a
61 * <code>"401 Unauthorized"</code> status really means that the client is <strong>not authenticated</strong>,
62 * and a <code>"403 Forbidden"</code> status means that the client is <strong>authenticated but not
63 * authorized</strong>.
64 * </p>
65 */
66 enum Decision {
67 /**
68 * ASAP authentication was attempted, but the {@code Authorization} header was missing, could not
69 * be parsed as containing a valid token, or is otherwise unacceptable.
70 * <p>
71 * Example reasons for this result include:
72 * </p>
73 * <ul>
74 * <li>The enforcement policy is {@link Policy#REQUIRE REQUIRE}, but the {@code Authorization} header is
75 * missing or does not contain a valid JWT.</li>
76 * <li>The token's issuer does not match its key ID.</li>
77 * <li>The token's audience is not valid (the token is meant for somebody else, not us).</li>
78 * <li>The token has invalid time information, such as claiming to have been created far in the future.</li>
79 * <li>The token has expired.</li>
80 * </ul>
81 * <p>
82 * Expected HTTP Status: {@code 401 Unauthorized} (See the {@link Decision Usage Note})
83 * </p>
84 */
85 NOT_AUTHENTICATED,
86
87 /**
88 * ASAP authentication is required, but no matching public key could be located to verify it.
89 * <p>
90 * This could be either a temporary problem accessing the key service or a permanent failure if the key
91 * does not exist. Either way, since the authenticity of the token could not be verified, its contents
92 * cannot be trusted.
93 * </p>
94 * <p>
95 * Expected HTTP Status: {@code 401 Unauthorized} (See the {@link Decision Usage Note})
96 * </p>
97 */
98 NOT_VERIFIED,
99
100 /**
101 * ASAP authentication was attempted by the client, but at least one of the validation constraints could
102 * not be satisfied (for example, if the token is not from an issuer that is authorized to use this resource).
103 * <p>
104 * Expected HTTP Status: {@code 403 Forbidden}
105 * </p>
106 */
107 NOT_AUTHORIZED,
108
109 /**
110 * ASAP authentication was successful, and the token satisfied all of the validator's authorization
111 * requirements.
112 */
113 AUTHORIZED,
114
115 /**
116 * ASAP authentication is explicitly disallowed, but an authentication header specifying an ASAP token was
117 * found.
118 * <p>
119 * Note that since the {@link Policy#REJECT REJECT} policy refuses all ASAP tokens regardless of their
120 * contents, tokens are not passed through their normal validity checks. Any token received is assumed
121 * to pass authentication and rejected as unauthorized, instead.
122 * </p><p>
123 * Expected HTTP Status: {@code 403 Forbidden}
124 * </p>
125 */
126 REJECTED,
127
128 /**
129 * ASAP authentication was not used for this request.
130 * <p>
131 * One of the following conditions applies:
132 * </p>
133 * <ul>
134 * <li>The policy is {@link Policy#IGNORE IGNORE} and it is unknown whether any token may have been
135 * provided, because the {@code Authorization} header was not examined.</li>
136 * <li>The policy is {@link Policy#OPTIONAL OPTIONAL} and no token was provided.</li>
137 * <li>The policy is {@link Policy#REJECT REJECT} and no token was provided.</li>
138 * </ul>
139 */
140 ABSTAIN;
141
142 /**
143 * If {@code true}, then the validation was successful (either an appropriate token was found or none was
144 * needed).
145 *
146 * @return {@code true} if this decision allows a request to proceed
147 */
148 public boolean isOk() {
149 return this == AUTHORIZED || this == ABSTAIN;
150 }
151 }
152 }
153