![](/img/trans.png)
[英]Scala (Play 2.4.x) How to call a class with @inject() annotation
[英]How can I verify an OAuth signature in Scala Play 2.4.X
為了與服務集成,我需要在Play 2.4(scala)服務器上實現REST端點。 該服務向我發送了一個GET請求,該請求已用他們給我的密鑰和秘密簽名。
我需要驗證請求是否來自他們
我的方法是:
val accessTokenOpt: Option[String] = request.headers.get(Security.AUTH_HEADER)
(accessTokenOpt, Security.consumer) match {
case (Some(accessToken), Some(consumer)) => {
val calculator = new OAuthCalculator(consumer, RequestToken("", ""))
val expected = WS.url(s"http://${request.host}${request.uri}").sign(calculator)
(expected.headers.get(Security.AUTH_HEADER), accessToken) match {
case (Some(exp), Some(actual)) if exp == actual =>
//good
case (Some(exp), Some(actual)) =>
//mismatch
case (e, a) =>
//missing tokens. :(
}
}
case _ => //bad
}
可能出現問題expected.headers.(Security.AUTH_HEADER)
返回None
我是否在代碼中缺少一些小東西,還是我的整個方法都不對?
我認為您的方法是正確的,並且從完全相同的參數計算得出的oauth簽名將始終匹配。 但是您必須考慮到您提到的一些參數,例如nonce和timestamp,為了做到這一點,我必須直接與執行簽名的Java類一起工作。
這是我設法使其工作的方式。 請記住,在我的情況下,與我的REST端點聯系的外部服務正在發送的Authorization標頭包含用於計算oauth_signature值的所有信息,但我擁有的oauth機密除外。
private def getProtocolFromRequest[T](request: Request[T]): String = {
// To handle the case where a SSL offloading is involved
request.headers.get(HeaderNames.X_FORWARDED_PROTO) match {
case Some(forwardedProto: String) => forwardedProto
case _ => if(request.secure) "https" else "http"
}
}
def isOAuthSignatureValid[T](request: Request[T]): Boolean = {
request.headers.get(com.ning.http.client.oauth.OAuthSignatureCalculator.HEADER_AUTHORIZATION) match {
case Some(authorizationHeaders) =>
val AuthRegex = ".*oauth_nonce=\"([^\"]*)\".*oauth_signature=\"([^\"]*)\".*oauth_timestamp=\"([^\"]*)\".*".r
authorizationHeaders match {
case AuthRegex(nonce: String, providedSignature: String, timestamp: String) =>
val signatureCalculator = new OAuthSignatureCalculator(new com.ning.http.client.oauth.ConsumerKey(oauthKey, oauthSecret), new com.ning.http.client.oauth.RequestToken(null, ""))
val params = request.queryString.map(query => new Param(query._1, query._2.head)).toSeq
val protocol = getProtocolFromRequest(request)
val url = s"$protocol://${request.host}${request.path}"
val expectedSignature = signatureCalculator.calculateSignature(
request.method,
Uri.create(url),
timestamp.toInt,
nonce,
new util.ArrayList(),
scala.collection.JavaConversions.seqAsJavaList(params)
)
expectedSignature.equals(URLDecoder.decode(providedSignature, "UTF-8"))
case _ => false
}
case _ => false
}
}
對我有用的流程如下:
希望可以幫助到別人
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.