mixi Developer Center (ミクシィ デベロッパーセンター)

mixiアプリ

mixiアプリ » 技術仕様(RESTful API方式) » PC » 外部サーバを呼び出してみよう

外部サーバを呼び出してみよう

mixiアプリは、Person & Friends APIを利用することによって、ソーシャルという特徴を持つことになります。それに加えて、インターネット上にある無数のWebサービス(外部サーバ)が提供するコンテンツとのマッシュアップによって、mixiアプリの魅力は何倍にも大きなものとなります。すでに海外などで人気を得ている OpenSocialアプリケーションのほとんどが、任意のWebサービスを呼び出してコンテンツを利用しています。単に外部のコンテンツを表示するだけでなく、ソーシャルグラフと関連付けることによって、新しいユーザ体験を提供することができます。

makerequest1

mixiアプリから外部サーバへ通信を行うための機構は、OpenSocial仕様においてGadgets Core JavaScript APIとして定義されています。具体的に外部サーバへ通信を行うための関数は、gadgets.io.makeReqeust()関数です。mixiアプリは、このmakeRequest()関数を利用することで、外部サーバからコンテンツを取得することができます。

makeRequest()関数の主要な機能

makeRequest()関数は非常に強力な機能をいくつか提供しますが、その使用方法は比較的シンプルです。この関数は、以下のような特徴を持っています。

  • HTTP Methodとして、GETやPOSTなど、ほとんどのMethodをサポートしている
  • 外部サーバから返却されるコンテンツについて、主要ないくつかの形式がサポートされており、JavaScriptにおいて扱いやすい形式に変換される
  • 署名などセキュリティに関する仕様が取り入れられているため、安全に外部サーバと通信することができる

makeRequest()関数を使用する際、以下の引数を指定します。

  • 取得したいコンテンツの位置を示すURL
  • 結果が返却された際に呼び出されるコールバック関数
  • 外部サーバへの要求に関するパラメータ

指定可能なパラメータは、gadgets.io.RequestParametersクラスに定義されています。これらのパラメータをうまく使うことで、外部サーバへの要求をカスタマイズすることが可能です。

gadgets.io.AUTHORIZATION

makeRequest()関数による外部サーバへのアクセスについて、署名を付与することができます。署名つきとするかどうかは、AUTHORIZATIONパラメータで指定します。

  • gadgets.io.AuthorizationType.NONE - 署名を付与しない
  • gadgets.io.AuthorizationType.SIGNED - 署名を付与する

※ mixiアプリから外部サーバへのOAuthによる認証認可要求は、現在サポートされていません。

gadgets.io.CONTENT_TYPE

CONTENT_TYPEパラメータにより、外部サーバから得られるコンテンツの期待する形式を指定することができます。この指定によって、コンテンツはJavaScriptオブジェクトに自動的に変換され、mixiアプリから扱いやすくなります。

  • gadgets.io.ContentType.DOM - XML形式の結果を期待する
  • gadgets.io.ContentType.FEED - RSSまたはATOM Feed形式の結果を期待する
  • gadgets.io.ContentType.JSON - JSON文字列形式の結果を期待する
  • gadgets.io.ContentType.TEXT - テキストそのままの形式の結果を期待する

そのほかにも、METHODパラメータによるHTTP Methodの指定や、POST_DATAパラメータによるPOST時に送信する情報の指定を行うことができます。

makeRequest()関数の第2引数で指定するコールバック関数には、結果を持つオブジェクトが呼び出し時に渡されます。そのオブジェクトは、以下のプロパティを持ちます。

  • data - 要求の際に指定したコンテンツの種別に応じて適切に変換された結果が保持される
  • rc - 要求の結果のHTTPステータスコードが保持される
  • errors - 要求の結果として何らかのエラーが返された際に、エラー情報が配列として保持される
  • text - 要求の結果として得られたコンテンツの文字列が保持される

これらのプロパティから、外部サーバから得られたコンテンツを利用することができます。

サンプルコード

以下のリストは、外部サーバからフィード文書を取得し、その結果を処理する例です。

var url = "http://your.server.host/recent";
var params = {};
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.FEED;
var post_data = {span : 7};
params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(post_data);
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.NONE;
gadgets.io.makeRequest(url, function(response) {
  var feed = response.data;
  var title = feed.Title;
  var link = feed.Link;
  // do something...
  var entries = feed.Entry;
  for (var i = 0; i < entries.length; i++) {
    var entry = entries[i];
    var entryTitle = entry.Title;
    var entryLink = entry.Link;
    // do something...
  }
}, params);

アクセス制限

mixi Platformの全体的な負荷対策として、mixiアプリ(PC版)から外部サーバに通信を行うためにご提供しているgadgets.io.makeRequest()関数について、以下の制限を実施いたします。

  • 接続先ホストへの通信が20回連続でタイムアウト(10秒)した場合、そのホストへの通信は15秒間行うことができない。
  • 15秒間の制限時間内にmakeRequest()にて通信を試みた場合には、エラーコード504を含むレスポンスが返されます(通常タイムアウトした場合と同じです)。

上記の各数値は、今後mixi Platformの稼働状況に応じて予告なく変更する可能性がございますので、ご了承ください。

署名付きリクエスト

makeRequest()関数を使ってmixiアプリは外部サーバと通信が行えるようになりますが、そのリクエストを受け付ける外部サーバ側では、そのリクエストの妥当性を確認することが必要となる場合が考えられます。具体的には、

  • mixi Platformから送信されたリクエストであること
  • リクエストの内容が改ざんされていないこと

をチェックすることにより、これらに違反する不正なリクエストを拒否することが可能となります。

署名付きリクエストを行うためには、AUTHORIZATIONパラメータにSIGNEDを指定します。以下のリストは、署名付きリクエストを行う処理の例です。

var url = "http://your.server.host/recent";
var params = {};
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
gadgets.io.makeRequest(url, function(response) {
  // do something...
}, params);

書名付きリクエストの際に外部サーバに対して送信されるリクエストについて、mixiアプリでは以下のパラメータ値となります。

  • oauth_consumer_key - "mixi.jp"
  • oauth_signature_method - "RSA-SHA1″

リクエストの内容は、各パラメータの値、oauth_signatureパラメータ値として付与された署名、そして公開鍵を使って、リクエストの妥当性を検証することができます。

公開鍵

-----BEGIN CERTIFICATE-----
MIIEKDCCApACCQCPJJVeNi+yjzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB1NoaWJ1eWExEzARBgNVBAoMCk1J
WEksIEluYy4xEDAOBgNVBAMMB21peGkuanAwHhcNMjMwNjAyMDYzNDM2WhcNMzMx
MTAxMDYzNDM2WjBWMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xEDAOBgNV
BAcMB1NoaWJ1eWExEzARBgNVBAoMCk1JWEksIEluYy4xEDAOBgNVBAMMB21peGku
anAwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDD5/0GV4/232lmAzKB
YUgo1rddFLQ+3OyyJXHN7TK3xpuetbDPY0cFisy/0Kk4l8RYDACyaPXYgyDVGY9q
YXHUeIVB8Ukg2GpvaE2M3Br/3yT8tADhnFOQaf3U8ghLoE8kyAUlLM3hDpBSdO1a
XKBE7fU9+xjLMl8inEhEabL/pil7wTn4TrwlB1INnW3iv++QCod5EvF0SXwt5o00
EVTU3RsXF5N04jg0RSxPDVoKmWHufuQf4xhyaBltlCrMMTtemGdSV7Bq7cFm0aeW
4Lwc0/sP7hYejIPztbtabNUgod33jxU0lVJWznkOBbyCq4HWhJ3W/vT6CMeNzmX7
qtig+rjbVcbZxa2NkcfTYcr+9FR7utJVv/8Rkb1eER5w179jDQ4d0JiPjpdZn6P/
7lJN3C+GsqBhTP6s2dOH0L3AaBLnOlrcgdiqupy5PG2u9E66BNue4g2hfE8P4ENb
9MXS9L9OK7DKV5rbSEy6G7iHQyneFWZXO7DaihAyhayK+SECAwEAATANBgkqhkiG
9w0BAQsFAAOCAYEALf68vYN8iPeXZM2h45R7/aSPmJN/EbBwwcyO27dv0B3PPOlr
bJ1bPHolSf61+87HKaemh5PPKieX3Tk7pOKFVJtPDQ2V4XDUyGYzNIFDFyTlaY1e
uvfMkOmHofkYEaqItMJOZgZ4c4gNPZnKxoFF97w0bSz56FEwfltd5Rqh83NClVXQ
NCKs0ZkMBJlK6RSnJ5pLbzAUYH2OvzZfNo0E61uSihr8v3GkTy4d6pWqKvuhCMd2
n8Y8DDGqKTdyGxCvwDpda20BUwsTY4ZF6hIdKDB7HEZsBPeZvs08ydzZmmQEDYiH
iNyJXzzTjWKfIC4xzjMHZ8devVqDNOolOBZEZ3QDWcPDF3UDUctRLrtd2p1Dq0B6
Ox7WwhCjT/KKGOKhQML/jwKZ3KCdNzyqj9ldSejCNNqAdkbUKh64fyDHhZEI+SD3
fiO7824WF+0ToPb6x/q+4fUeYxzSuvJ3P1HQCDgZOUhxX9NMOR8Qfp1BuT769MKm
rmC1N6t9cWnkTk+v
-----END CERTIFICATE-----

署名付きリクエストの検証

この記事では、署名付きリクエストをどのように検証するかを説明します。もしあなたが署名付きリクエストとは何かわからない場合や、なぜこれを使わなければならないのかわからない場合は、署名付きリクエストの紹介ページをチェックしてください。

※ ここより先の内容は、「Validating Signed Requests」の翻訳に一部修正を加えたものです。
http://wiki.opensocial.org/index.php?title=Validating_Signed_Requests

暗号化キーを入手する

署名付きリクエストは、現在3つのパラメータを含みます。

  • oauth_consumer_key
  • xoauth_signature_publickey
  • oauth_signature_method

oauth_consumer_keyパラメータは、リクエストが送信されたコンテナを示します。oauth_signature_methodパラメータは、リクエストを署名するために使われたメソッドを示します。RSA-SHA1で署名されたリクエストのために、 xoauth_signature_publickeyはリクエストを署名するために使われた公開鍵の名前を含みます。

HMAC-SHA1のために、あなたはあなたのアプリケーションとコンテナの間でSecret keyを確立する必要があるでしょう。各コンテナは、それをするために異なるメカニズムを持ちますので、共有Secret keyを確立することに関する情報を得るために、あなたが対象とするコンテナのドキュメントを参照してください。

RSA-SHA1のために、あなたはxoauth_signature_publickeyによって参照される証明書を入手する必要があるでしょう。あなたの利便性のために、各証明書へのリンクを含む各コンテナで利用可能な公開鍵の一覧が https://opensocialresources.appspot.com/certificates/ にあります。このサイトは、利便性のためのみのものであり、各コンテナによって承認されたリストではありません!ベストなセキュリティにおいて、承認された公開鍵の位置を検証するために、必ずあなたのコンテナのドキュメントをチェックしてください!

証明書は、あなたがパラメータを検証したい度に取得されるべきではありません。その代わりに、 xoauth_signature_publickey、oauth_consumer_key、そしてoauth_signature_methodの値でインデックスされた、サーバサイドの鍵キャッシュ機構を実装してください。もしそれらの値に変更があった際には、あなたはあなたの鍵キャッシュの中で、新しい証明書をダウンロードし格納する必要があるでしょう。

OAuth署名メカニズム

パラメータの署名は、OAuthパラメータ署名仕様に従って実装されます。

署名ベース文字列を生成することに関する情報は、このページをチェックしてください。

http://oauth.net/core/1.0/#rfc.section.A.5.1

PHP

クライアントサイドコード

あなたのクライアントコードは、以下の作法においてリクエストを作るべきです。私たちは、gadgets.io.AuthorizationType.SIGNEDリクエストを指定し、そしてJSONとして返される結果を期待するでしょう。

function makeSignedRequest() {
  var params = {};
  params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
  params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
  var url = "http://graargh.returnstrue.com/buh/fetchme.php";
  gadgets.io.makeRequest(url, response, params);
};

function response(ret) {
  output(ret.data);

  var html = [ ret.data.validated, "<br />",
    "oauth_consumer_key: ", ret.data.query.oauth_consumer_key, "<br />",
    "oauth_nonce: ", ret.data.query.oauth_nonce, "<br />",
    "oauth_signature: ", ret.data.query.oauth_signature, "<br />",
    "oauth_signature_method: ", ret.data.query.oauth_signature_method, "<br />",
    "oauth_timestamp: ", ret.data.query.oauth_timestamp, "<br />",
    "oauth_token: ", ret.data.query.oauth_token, "<br />",
    "opensocial_app_id: ", ret.data.query.opensocial_app_id, "<br />",
    "opensocial_owner_id: ", ret.data.query.opensocial_owner_id, "<br />",
    "xoauth_signature_publickey: ", ret.data.query.xoauth_signature_publickey
].join("");

  output(html);
};

makeSignedRequest();

サーバサイドコード

以下のコードは、fetchme.phpというサーバサイドコードとなります。このコードは、オープンソースのOAuthライブラリプロジェクトにあるOAuth.php (リビジョン 526)に依存しています。

コードは、以下の手順で実装されています:

  • OAuthSignatureMethod_RSA_SHA1を継承したMixiSignatureMethodクラスを作成。
  • 受け取ったリクエストからOAuthRequestオブジェクトを生成。
  • MixiSignatureMethodのインスタンスを生成。
  • MixiSignatureMethodクラスを使ってリクエストをチェック。
  • JSONオブジェクトを出力。

この例は、プロダクション品質のコードではありません。ただ単に、あなたがサーバサイドで署名付きリクエストを検証することを試すための手順のデモに過ぎません。

require_once("OAuth.php");

class MixiSignatureMethod extends OAuthSignatureMethod_RSA_SHA1 {
  protected function fetch_public_cert(&$request) {
  return <<< EOD
-----BEGIN CERTIFICATE-----
.................................. ... 公開鍵を貼り付けてください ...
.................................. -----END CERTIFICATE----- EOD; } protected function fetch_private_cert(&$request){} } //Build a request object from the current request $request = OAuthRequest::from_request(null, null, array_merge($_GET, $_POST)); //Initialize the new signature method $signature_method = new MixiSignatureMethod(); //Check the request signature @$signature_valid = $signature_method->check_signature($request, null, null, $_GET["oauth_signature"]); //Build the output object $payload = array(); if ($signature_valid == true) { $payload["validated"] = "Success! The data was validated"; } else { $payload["validated"] = "This request was spoofed"; } //Add extra parameters to help debugging $payload["query"] = array_merge($_GET, $_POST); $payload["rawpost"] = file_get_contents("php://input"); //Return the response as JSON print(json_encode($payload));

結果

あなたがサーバコードに対してクライアントサイドのスクリプトを実行したとき、"response"関数は以下のオブジェクトのひとつを伴って呼び出されるでしょう:

もしリクエストが検証された場合:

{ "validated" : "Success! The data was validated",
  "query" : {  }
}

もしリクエストが検証されなかった場合:

{ "validated" : "This request was spoofed",
  "query" : {  }
}

この結果は以下の書式で出力されます:

Success! The data was validated
oauth_consumer_key: mixi.jp
oauth_nonce: c970afeb19325be3
oauth_signature: #### REALLY LONG STRING ###
oauth_signature_method: RSA-SHA1
oauth_timestamp: 1201225242
oauth_token:
opensocial_appid: ############
opensocial_ownerid: ############
xoauth_signature_publickey: pub.1199819524.-1556113204990931254.cer

OAuth.php に依存しないサーバサイドのサンプルコードは次となります。

$cert = <<< EOD
-----BEGIN CERTIFICATE-----
.................................. ... 公開鍵を貼り付けてください ...
.................................. -----END CERTIFICATE----- EOD; $publickeyid = openssl_get_publickey($cert); $signature = $_REQUEST["oauth_signature"]; $method = $_SERVER['REQUEST_METHOD']; $url = 'http://sample.server-side.code.jp/xxx/sample.php'; $params = $_REQUEST; unset($params['oauth_signature']); ksort($params); $queryStrs = array(); foreach($params as $key => $val){ $queryStrs[] = $key.'='.urlencode($val); } $baseStr = implode('&', array_map('urlencode', array($method, $url, implode('&', $queryStrs)))); $ok = openssl_verify($baseStr, base64_decode($signature), $publickeyid); openssl_free_key($publickeyid);

Java

クライアントサイドコード

var servletUrl="http://oauthtest.s42.eatj.com/oauth/SignedFetchVerifyServlet";
function response(data) {
  document.getElementById('dom_handle').innerHTML=data.text;
};
function request() {
  var params={};
  params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
  gadgets.io.makeRequest(servletUrl,response,params);
};
gadgets.util.registerOnLoadHandler(request);

サーバサイドコード

コードは以下の手順で実装されます:

  • OAuthServiceProviderを生成します。
  • OAuthConsumerを生成し、mixiの証明書を伴うRSA証明書を投入します。
  • HttpServletRequestからOAuthMessageを展開します。
  • consumerを使ってOAuthAccessorを生成します。
  • accessorを使ってOAuthMessageを検証します。

このコードは、オープンソースのOAuthライブラリプロジェクトのJava実装に依存します。

この例は、プロダクション品質のコードではありません。ただ単に、あなたがサーバサイドで署名付きリクエストを検証することを試すための手順のデモに過ぎません。

package net.oauth.example.provider.servlets;

import net.oauth.OAuth;
import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthProblemException;
import net.oauth.OAuthServiceProvider;
import net.oauth.OAuthValidator;
import net.oauth.SimpleOAuthValidator;
import net.oauth.server.OAuthServlet;
import net.oauth.signature.RSA_SHA1;

import java.util.ArrayList;
import java.io.IOException;
import java.util.Map;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SignedFetchVerifyServlet extends HttpServlet {

  private final static String CERTIFICATE =
    "-----BEGIN CERTIFICATE-----\n"
+ "..................................\n" + "... 公開鍵を貼り付けてください ...\n"
+ "..................................\n" + "-----END CERTIFICATE-----"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { verifyFetch(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { verifyFetch(req, resp); } private void verifyFetch(HttpServletRequest request, HttpServletResponse resp) throws IOException, ServletException { resp.setContentType("text/html; charset=UTF-8"); PrintWriter out = resp.getWriter(); try { OAuthServiceProvider provider = new OAuthServiceProvider(null, null, null); OAuthConsumer consumer = new OAuthConsumer(null, "mixi.jp", null, provider); consumer.setProperty(RSA_SHA1.X509_CERTIFICATE, CERTIFICATE); String method = request.getMethod(); String requestUrl = getRequestUrl(request); List requestParameters = getRequestParameters(request); OAuthMessage message = new OAuthMessage(method, requestUrl, requestParameters); OAuthAccessor accessor = new OAuthAccessor(consumer); out.print("*** OAuthMessage Params:"); out.print("URL: " + OAuthServlet.htmlEncode(message.URL)); for (java.util.Map.Entry param : message.getParameters()) { String key = param.getKey().toString(); String value = param.getValue().toString(); out.print(""); out.print("Param Name-->" + OAuthServlet.htmlEncode(key)); out.print(" "); out.print("Value-->" + OAuthServlet.htmlEncode(value)); } out.print(""); out.print(" VALIDATING SIGNATURE "); out.print(""); OAuthValidator validator = new SimpleOAuthValidator(); validator.validateMessage(message, accessor); out.print("REQUEST STATUS::OK"); out.print(""); } catch (OAuthProblemException ope) { out.print(""); out.print("OAuthProblemException-->" + OAuthServlet.htmlEncode(ope.getProblem())); } catch (Exception e) { out.println(e); System.out.println(e); throw new ServletException(e); } finally { out.flush(); } } /** * Constructs and returns the full URL associated with the passed request * object. * * @param request Servlet request object with methods for retrieving the * various components of the request URL */ public static String getRequestUrl(HttpServletRequest request) { StringBuilder requestUrl = new StringBuilder(); String scheme = request.getScheme(); int port = request.getLocalPort(); requestUrl.append(scheme); requestUrl.append("://"); requestUrl.append(request.getServerName()); if ((port != 0) && ( (scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443))) { requestUrl.append(":"); requestUrl.append(port); } requestUrl.append(request.getContextPath()); requestUrl.append(request.getServletPath()); return requestUrl.toString(); } /** * Constructs and returns a List of OAuth.Parameter objects, one per * parameter in the passed request. * * @param request Servlet request object with methods for retrieving the * full set of parameters passed with the request */ public static List getRequestParameters(HttpServletRequest request) { List parameters = new ArrayList(); for (Object e : request.getParameterMap().entrySet()) { Map.Entry entry = (Map.Entry) e; String[] values = (String[])entry.getValue(); for (String value : values) { parameters.add(new OAuth.Parameter(entry.getKey(), value)); } } return parameters; } }

結果

あなたがサーバコードに対してクライアントサイドのスクリプトを実行したとき、そしてリクエストが検証されたとき:

*** OAuthMessage Params:
URL: http://oauthtest.s42.eatj.com/oauth/SignedFetchVerifyServlet
Param Name-->oauth_consumer_key Value-->mixi.jp
Param Name-->oauth_nonce Value-->7fe2ce6b24e17c86
Param Name-->opensocial_app_id Value-->10449685582340194994
Param Name-->opensocial_viewer_id Value-->xxxxxxxx
Param Name-->oauth_timestamp Value-->1211519778
Param Name-->opensocial_owner_id Value-->xxxxxxxx
Param Name-->oauth_signature Value-->eYwX2yWLpOZ+gb5oEFeIy+EM3j237nrj/1rj3yp69jgo
/QaPk/OnXbXP9imEcERxtQLj9QqDD8cjbjMJ46VINc7b
Lab8qER1Xhkf4tTIkwfFXJW9tjQMBuGO8OVf9v0UAjAr
uWfSN331LLgGFecKQR5UTD0qAAyzTnFY9aSmqg8=
Param Name-->xoauth_signature_publickey Value-->pub.1199819524.-1556113204990931254.cer
Param Name-->oauth_token Value-->
Param Name-->oauth_signature_method Value-->RSA-SHA1
VALIDATING SIGNATURE
REQUEST STATUS::OK

C#

サーバサイドコード

このコードは、オープンソースのOAuthライブラリプロジェクトのC#向けOAuthライブラリに依存しています。

この例は、プロダクション品質のコードではありません。ただ単に、あなたがサーバサイドで署名付きリクエストを検証することを試すための手順のデモに過ぎません。

// -----------------------------------------------------------------------------------
//
//  OBasePage.cs to validate oAuth signature - .NET
//  by XtremeHeights
//  Last Modification: 4th Oct 2008
//
//  For more information, visit:
//  http:/www.xtremeheights.com/
//  email: contact@xtremeheights.com
//
//
//  Thanks:
//  Khushal Patel for creating plug & plug code for implementing oAuth in .NET
//  Nemesh Singh for fixing the code which started spoofing every request after 25th sep 2008
//
// -----------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Configuration;
using System.Web;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Collections.Specialized;
using OAuth;

public class oBasePage : System.Web.UI.Page
{
  HttpContext htp;
  public oBasePage(HttpContext _htp)
  {
    htp = _htp;
  }

  public bool isvalidrequest()
  {
    //If you want to import certificate file directly then uncomment the below line and comment the certificate
    //X509Certificate Cert = X509Certificate.CreateFromCertFile(htp.Request.PhysicalApplicationPath + "/bin/pub.1199819524.-1556113204990931254.cer");

    X509Certificate2 cert = new X509Certificate2();
    cert.Import(Encoding.ASCII.GetBytes(
@"-----BEGIN CERTIFICATE-----
.................................. ... 公開鍵を貼り付けてください ...
.................................. -----END CERTIFICATE-----")); //Getting Post variables string http_params; NameValueCollection _p = htp.Request.Form; Hashtable _hp = new Hashtable(); foreach (string k in _p.Keys) { if (k != null) { _hp[k] = _p[k]; } } SortedList _ps = new SortedList((IDictionary)_hp); string[] pairs1 = new string[_ps.Keys.Count]; int l = 0; foreach (string name in _ps.Keys) { pairs1[l++] = name + "=" + Uri.EscapeDataString(_ps[name].ToString()); } http_params = (String.Join("&", pairs1)); if (_ps.Keys.Count != 0) { http_params = "&" + http_params; } /* RSACryptoServiceProvider Provider = CertUtil.GetCertPublicKey(Cert); // if importing the file directly... */ RSACryptoServiceProvider Provider = (RSACryptoServiceProvider)cert.PublicKey.Key; OAuth.OAuthBase ba = new OAuthBase(); string signature = (htp.Request.QueryString["oauth_signature"]); string baseString = ba.GenerateSignatureBase(htp.Request.Url, htp.Request.QueryString["oauth_consumer_key"], "", htp.Request.QueryString["oauth_token"], "", htp.Request.HttpMethod, htp.Request.QueryString["oauth_timestamp"], htp.Request.QueryString["oauth_nonce"], "RSA-SHA1", http_params); byte[] sign = Convert.FromBase64String(signature); byte[] bstring = Encoding.UTF8.GetBytes(baseString); htp.Response.Write(htp.Request.QueryString["oauth_token"]); return (Provider.VerifyData(bstring, "SHA1", sign)); } }

Perl

サーバサイドコード

このコードは、CPANにて公開されているCrypt::OpenSSL::CAモジュールおよびOAuth::Liteモジュールに依存しています。

http://search.cpan.org/~domq/Crypt-OpenSSL-CA-0.21/
http://search.cpan.org/~lyokato/OAuth-Lite-1.30/

この例は、プロダクション品質のコードではありません。ただ単に、あなたがサーバサイドで署名付きリクエストを検証することを試すための手順のデモに過ぎません。

#!/usr/bin/perl
use strict;
use warnings;

use Crypt::OpenSSL::CA;
use OAuth::Lite::ServerUtil;
use URI;
use URI::QueryParam;

my $ca = << '__CERTIFICATE__';
-----BEGIN CERTIFICATE-----
.................................. ... 公開鍵を貼り付けてください ...
.................................. ----END CERTIFICATE----- __CERTIFICATE__ my $public_key = Crypt::OpenSSL::CA::X509->parse($ca) ->get_public_key() ->to_PEM(); my $method = $ENV{REQUEST_METHOD}; my $url = 'http://your.host.name/verify_signature.pl'; my $query_string = $ENV{QUERY_STRING}; if ($method eq 'POST') { $query_string .= '&' . <STDIN>; } my $params = URI->new('?' . $query_string)->query_form_hash(); my $util = OAuth::Lite::ServerUtil->new(); $util->support_signature_method('RSA_SHA1'); my $ret = $util->verify_signature( method => $method, url => $url, params => $params, consumer_secret => $public_key, ); print 'Status: 200', "\n"; print 'Content-Type: text/plain', "\n"; print "\n"; print $ret ? 'Success' : 'Failure', "\n";

このページの上部へ