|
Play Framework/Scala example source code file (OAuthRequestVerifier.scala)
The OAuthRequestVerifier.scala Play Framework example source code/* * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> */ package play.api.libs.oauth import play.api.mvc.RequestHeader import play.core.parsers.FormUrlEncodedParser import java.util.Locale import javax.crypto.spec.SecretKeySpec import javax.crypto.Mac import org.apache.commons.codec.binary.Base64 import org.specs2.matcher.MustExpectations._ import org.specs2.matcher.Matchers._ import _root_.oauth.signpost.{ OAuth => SPOAuth } import org.specs2.matcher.MatchResult /** * Verifies OAuth requests */ object OAuthRequestVerifier { import SPOAuth.{ percentEncode, percentDecode } /** * Verify that the given request is a valid OAuth request given the consumer key and request token */ def verifyRequest(request: RequestHeader, body: Array[Byte], hostUrl: String, consumerKey: ConsumerKey, requestToken: RequestToken): MatchResult[_] = { val method = request.method val baseUrl = hostUrl + request.path request.headers.get("Authorization") must beSome.like { case authorization => authorization must startWith("OAuth ") val oauthParams = authorization.drop(6).split(", ").map { param => val splitted = param.split("=") val key = percentDecode(splitted(0)) val rawValue = splitted(1) rawValue must startWith("\"") rawValue must endWith("\"") val value = percentDecode(rawValue.drop(1).dropRight(1)) key -> value } val oauthParamsMap = oauthParams.toMap val oauthSignature = oauthParamsMap.get("oauth_signature") val oauthToken = oauthParamsMap.get("oauth_token") val oauthConsumerKey = oauthParamsMap.get("oauth_consumer_key") val oauthSignatureMethod = oauthParamsMap.get("oauth_signature_method") val oauthTimestamp = oauthParamsMap.get("oauth_timestamp") // Verify various fields oauthToken must beSome(requestToken.token) oauthConsumerKey must beSome(consumerKey.key) oauthSignatureMethod must beSome("HMAC-SHA1") oauthTimestamp must beSome.like { case timestamp => // Verify no more than 100 seconds in the past timestamp.toLong must beGreaterThan(System.currentTimeMillis() / 1000 - 100) } // Verify the signature val collectedParams = oauthParams.filterNot(_._1 == "oauth_signature") ++ request.queryString.toSeq.flatMap { case (key, values) => values.map(value => key -> value) } // If the body is form URL encoded, must include body parameters val collectedParamsWithBody = request.contentType match { case Some(formUrlEncoded) if formUrlEncoded.startsWith("application/x-www-form-urlencoded") => val form = FormUrlEncodedParser.parse(new String(body, "US-ASCII")).toSeq.flatMap { case (key, values) => values.map(value => key -> value) } collectedParams ++ form case _ => collectedParams } oauthSignature must beSome.like { case signature => val ourSignature = signParams(method, baseUrl, collectedParamsWithBody, consumerKey.secret, requestToken.secret) signature must_== ourSignature } } } def signParams(method: String, baseUrl: String, params: Seq[(String, String)], consumerSecret: String, tokenSecret: String) = { // See https://dev.twitter.com/docs/auth/creating-signature // Params must be percent encoded before they are sorted val parameterString = params.map { case (key, value) => percentEncode(key) -> percentEncode(value) }.sorted.map { case (key, value) => s"$key=$value" }.mkString("&") val signatureBaseString = s"${method.toUpperCase(Locale.ENGLISH)}&${percentEncode(baseUrl)}&${percentEncode(parameterString)}" val signingKey = s"${percentEncode(consumerSecret)}&${percentEncode(tokenSecret)}" val keySpec = new SecretKeySpec(signingKey.getBytes("US-ASCII"), "HmacSHA1") val mac = Mac.getInstance("HmacSHA1") mac.init(keySpec) val signature = mac.doFinal(signatureBaseString.getBytes("US-ASCII")) new String(Base64.encodeBase64(signature), "US-ASCII") } } Other Play Framework source code examplesHere is a short list of links related to this Play Framework OAuthRequestVerifier.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.