private void validateMessage(OAuthAccessor accessor, MessageInfo info, boolean tokenEndpoint) throws OAuthException, IOException, URISyntaxException { info.message.validateMessage(accessor, new FakeTimeOAuthValidator()); String bodyHash = info.message.getParameter("oauth_body_hash"); if (tokenEndpoint && bodyHash != null) { throw new RuntimeException("Can't have body hash on token endpoints"); } SignatureType sigType = OAuthUtil.getSignatureType(tokenEndpoint, info.request.getHeader("Content-Type")); switch (sigType) { case URL_ONLY: break; case URL_AND_FORM_PARAMS: if (bodyHash != null) { throw new RuntimeException("Can't have body hash in form-encoded request"); } break; case URL_AND_BODY_HASH: if (bodyHash == null) { throw new RuntimeException("Requiring oauth_body_hash parameter"); } byte[] received = Base64.decodeBase64(CharsetUtil.getUtf8Bytes(bodyHash)); byte[] expected = DigestUtils.sha(info.rawBody); if (!Arrays.equals(received, expected)) { throw new RuntimeException("oauth_body_hash mismatch"); } } }
private String hasExtraParams(OAuthMessage message) { for (Entry<String, String> param : OAuthUtil.getParameters(message)) { // Our request token URL allows "param" as a query param, and also oauth params of course. if (!param.getKey().startsWith("oauth") && !param.getKey().equals("param")) { return param.getKey(); } } return null; }
// Loosely based off net.oauth.OAuthServlet, and even more loosely related // to the OAuth specification private MessageInfo parseMessage(HttpRequest request) { MessageInfo info = new MessageInfo(); info.request = request; String method = request.getMethod(); ParsedUrl parsed = new ParsedUrl(request.getUri().toString()); List<OAuth.Parameter> params = Lists.newArrayList(); params.addAll(parsed.getParsedQuery()); if (!validParamLocations.contains(OAuthParamLocation.URI_QUERY)) { // Make sure nothing OAuth related ended up in the query string for (OAuth.Parameter p : params) { if (p.getKey().contains("oauth_")) { throw new RuntimeException("Found unexpected query param " + p.getKey()); } } } // Parse authorization header if (validParamLocations.contains(OAuthParamLocation.AUTH_HEADER)) { String aznHeader = request.getHeader("Authorization"); if (aznHeader != null) { info.aznHeader = aznHeader; for (OAuth.Parameter p : OAuthMessage.decodeAuthorization(aznHeader)) { if (!p.getKey().equalsIgnoreCase("realm")) { params.add(p); } } } } // Parse body info.body = request.getPostBodyAsString(); try { info.rawBody = IOUtils.toByteArray(request.getPostBody()); } catch (IOException e) { throw new RuntimeException("Can't read post body bytes", e); } if (OAuth.isFormEncoded(request.getHeader("Content-Type"))) { params.addAll(OAuth.decodeForm(request.getPostBodyAsString())); // If we're not configured to pass oauth parameters in the post body, double check // that they didn't end up there. if (!validParamLocations.contains(OAuthParamLocation.POST_BODY)) { if (info.body.contains("oauth_")) { throw new RuntimeException("Found unexpected post body data" + info.body); } } } // Return the lot info.message = new OAuthMessage(method, parsed.getLocation(), params); // Check for trusted parameters if (checkTrustedParams) { if (!"foo".equals(OAuthUtil.getParameter(info.message, "oauth_magic"))) { throw new RuntimeException("no oauth_trusted=foo parameter"); } if (!"bar".equals(OAuthUtil.getParameter(info.message, "opensocial_magic"))) { throw new RuntimeException("no opensocial_trusted=foo parameter"); } if (!"quux".equals(OAuthUtil.getParameter(info.message, "xoauth_magic"))) { throw new RuntimeException("no xoauth_magic=quux parameter"); } trustedParamCount += 3; } return info; }