public static boolean requestContainsJwt(HttpServletRequest request) { return extractJwt(request) != null; }
/** * Canonicalize the given {@link CanonicalHttpRequest} and hash it. * This request hash can be included as a JWT claim to verify that request components are genuine. * @param request {@link CanonicalHttpRequest} to be canonicalized and hashed * @return {@link String} hash suitable for use as a JWT claim value * @throws UnsupportedEncodingException if the {@link java.net.URLEncoder} cannot encode the request's field's characters * @throws NoSuchAlgorithmException if the hashing algorithm does not exist at runtime */ public static String computeCanonicalRequestHash(CanonicalHttpRequest request) throws UnsupportedEncodingException, NoSuchAlgorithmException { // prevent the code in this method being repeated in every call site that needs a request hash, // encapsulate the knowledge of the type of hash that we are using return JwtUtil.computeSha256Hash(canonicalize(request)); }
ComparableParameter(Map.Entry<String, String[]> parameter) throws UnsupportedEncodingException { this.parameter = parameter; String name = safeToString(parameter.getKey()); List<String> sortedValues = Arrays.asList(parameter.getValue()); Collections.sort(sortedValues); String value = StringUtils.join(sortedValues, ','); this.key = JwtUtil.percentEncode(name) + ' ' + JwtUtil.percentEncode(value); // ' ' is used because it comes before any character // that can appear in a percentEncoded string. }
if (!JwtUtil.requestContainsJwt(request))
@Override protected boolean shouldProcess(HttpServletRequest request) { String jwtToken = JwtUtil.extractJwt(request); if (!StringUtils.isEmpty(jwtToken)) { try { Jwt jwt = new SimpleJwtParser().parse(jwtToken); boolean wasIssuedByHost = jwtWasIssuedByHost(jwt.getIssuer()); log.debug("wasIssuedByHost={}", wasIssuedByHost); return wasIssuedByHost; } catch (Exception e) { // one of the many possible JWT reading exceptions was thrown - log for debugging and let the invoking test fail log.error(String.format("Failed to read JWT token '%s' due to exception: ", jwtToken), e); } } log.debug("JWT token was empty: should not process request"); return false; }
private static String canonicalizeUri(CanonicalHttpRequest request) throws UnsupportedEncodingException { String path = StringUtils.defaultIfBlank(StringUtils.removeEnd(request.getRelativePath(), "/"), "/"); final String separatorAsString = String.valueOf(CANONICAL_REQUEST_PART_SEPARATOR); // If the separator is not URL encoded then the following URLs have the same query-string-hash: // https://djtest9.jira-dev.com/rest/api/2/project&a=b?x=y // https://djtest9.jira-dev.com/rest/api/2/project?a=b&x=y path = path.replaceAll(separatorAsString, JwtUtil.percentEncode(separatorAsString)); return path.startsWith("/") ? path : "/" + path; }
/** * Write a form-urlencoded document into the given stream, containing the * given sequence of name/parameter pairs. */ private static void percentEncode(Iterable<? extends Map.Entry<String, String[]>> parameters, OutputStream into) throws IOException { if (parameters != null) { boolean first = true; for (Map.Entry<String, String[]> parameter : parameters) { if (first) { first = false; } else { into.write(JwtUtil.QUERY_PARAMS_SEPARATOR); } into.write(JwtUtil.percentEncode(safeToString(parameter.getKey())).getBytes()); into.write('='); List<String> percentEncodedValues = new ArrayList<String>(parameter.getValue().length); for (String value : parameter.getValue()) { percentEncodedValues.add(JwtUtil.percentEncode(value)); } into.write(StringUtils.join(percentEncodedValues, ENCODED_PARAM_VALUE_SEPARATOR).getBytes()); } } }