Skip to content

Commit

Permalink
Move the api suffix checking into the obo authenticator: extractCrede…
Browse files Browse the repository at this point in the history
…ntial0()

Signed-off-by: Ryan Liang <jiallian@amazon.com>
  • Loading branch information
RyanL1997 committed Aug 3, 2023
1 parent 0bd2545 commit 55a6a33
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ public class SecurityRestFilter {
private static final String HEALTH_SUFFIX = "health";
private static final String WHO_AM_I_SUFFIX = "whoami";

private static final String ON_BEHALF_OF_SUFFIX = "onbehalfof";

private static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" + "(.*)";
private static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX);

Expand Down Expand Up @@ -260,17 +258,6 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha
);
}
}

if (HTTPHelper.containsOBOToken(request)) {
if (request.method() == Method.POST && ON_BEHALF_OF_SUFFIX.equals(suffix)) {
final OpenSearchException exception = ExceptionUtils.invalidUsageOfOBOTokenException();
log.error(exception.toString());
auditLog.logBadHeaders(request);
channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, exception));
return true;
}
}

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand All @@ -28,6 +29,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.OpenSearchException;
import org.opensearch.OpenSearchSecurityException;
import org.opensearch.SpecialPermission;
import org.opensearch.common.settings.Settings;
Expand All @@ -36,11 +38,19 @@
import org.opensearch.rest.RestRequest;
import org.opensearch.security.auth.HTTPAuthenticator;
import org.opensearch.security.authtoken.jwt.EncryptionDecryptionUtil;
import org.opensearch.security.ssl.util.ExceptionUtils;
import org.opensearch.security.user.AuthCredentials;
import org.opensearch.security.util.keyUtil;

import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX;
import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX;

public class OnBehalfOfAuthenticator implements HTTPAuthenticator {

private static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" + "(.*)";
private static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX);
private static final String ON_BEHALF_OF_SUFFIX = "onbehalfof";

protected final Logger log = LogManager.getLogger(this.getClass());

private static final Pattern BEARER = Pattern.compile("^\\s*Bearer\\s.*", Pattern.CASE_INSENSITIVE);
Expand Down Expand Up @@ -194,6 +204,14 @@ private AuthCredentials extractCredentials0(final RestRequest request) {

final AuthCredentials ac = new AuthCredentials(subject, roles, backendRoles).markComplete();

Matcher matcher = PATTERN_PATH_PREFIX.matcher(request.path());
final String suffix = matcher.matches() ? matcher.group(2) : null;
if (request.method() == RestRequest.Method.POST && ON_BEHALF_OF_SUFFIX.equals(suffix)) {
final OpenSearchException exception = ExceptionUtils.invalidUsageOfOBOTokenException();
log.error(exception.toString());
return null;
}

for (Entry<String, Object> claim : claims.entrySet()) {
ac.addAttribute("attr.jwt." + claim.getKey(), String.valueOf(claim.getValue()));
}
Expand Down
39 changes: 0 additions & 39 deletions src/main/java/org/opensearch/security/support/HTTPHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
import java.util.List;
import java.util.Map;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import org.apache.logging.log4j.Logger;

import org.opensearch.rest.RestRequest;
Expand Down Expand Up @@ -103,40 +100,4 @@ public static boolean containsBadHeader(final RestRequest request) {

return false;
}

public static boolean containsOBOToken(final RestRequest request) {
final Map<String, List<String>> headers;

if (request != null && (headers = request.getHeaders()) != null) {
List<String> authHeaders = headers.get("Authorization");
if (authHeaders != null && !authHeaders.isEmpty()) {
// Iterate through the list of 'Authorization' headers, checking each for the 'Bearer' prefix.
for (String authHeader : authHeaders) {
if (authHeader != null && authHeader.startsWith("Bearer ")) {
// Header found, extract the token to verify it's an OBO token.
String token = authHeader.substring("Bearer ".length());
if (isOBOToken(token)) {
return true;
}
}
}
}
}

return false;
}

private static boolean isOBOToken(String token) {
String tokenIdentifierClaimKey = "typ";
String tokenIdentifier = "obo";

Jws<Claims> claimsJws = Jwts.parserBuilder().build().parseClaimsJws(token);
Claims claims = claimsJws.getBody();

if (claims.containsKey(tokenIdentifierClaimKey) && tokenIdentifier.equals(claims.get(tokenIdentifierClaimKey))) {
return true;
}
return false;
}

}

0 comments on commit 55a6a33

Please sign in to comment.