Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

<?xml version="1.0" encoding="utf-8"?>
<html>
Version|opensocial-0.7|opensocial-0.8

<div style="float:right; margin: 0 0 10px 10px;">

Table of Contents
outlinetrue
indent20px
stylenone
printablefalse

</div>

This article describes how to validate a signed request. If you're unsure of what a signed request is or why you would want to use one, please check out the Introduction To Signed Requests page.

Obtaining encryption keys

Signed requests currently include three parameters:

  1. oauth_consumer_key
  2. xoauth_signature_publickey
  3. oauth_signature_method

The *

...

auth_consumer_key

...

* parameter indicates the container from which the request is being sent. The *

...

oauth_signature_method

...

* parameter parameter indicates the method used to sign the request. For requests signed with RSA-SHA1, the *

...

}xoauth_signature_publickey

...

* contains the name of the public key used to sign the request.

...

For RSA-SHA1, you will need to obtain the certificate referenced by

...

xoauth_signature_publickey

...

. For your convenience, there is a list of public keys for each container available at https://opensocialresources.appspot.com/certificates/ along with links to each certificate. This site is for convenience only and not approved by the containers listed! For the best security, be sure to check your containers documentation to verify the location of the appropriate public key!

Certificates should not be fetched each time you want to validate parameters - instead, implement a server side key cache indexed on the value of

...

xoauth_signature_publickey

...

,

...

oauth_consumer_key

...

}e}, and

...

{{oauth_signature_method

...

. If these value change, you will need to pull a new certificate down and store it in your key cache.

OAuth Signing Mechanism

The parameter signing is implemented according to the OAuth parameter signing specification.

Check [ this page|http://oauth.net/core/1.0/#rfc.section.A.5.1] for information about generating the Signature Base String.

PHP

Client side code

Your client code should make a request in the following manner. We will be specifying a

...

gadgets.io.AuthorizationType.SIGNED

...

request, and will expect the response to be returned as JSON.

Code Block

...

javascript

...

panel
javascript

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);


 };
Panel
function

 
 function response(ret) {


   output(ret.data);
var html = [

 
   var html = [ ret.data.validated, "
<br />",

...

Panel

     "oauth_consumer_key: ", ret.data.query.oauth_consumer_key, "
<br />",

...

Panel

     "oauth_nonce: ", ret.data.query.oauth_nonce, "
<br />",

...

Panel

     "oauth_signature: ", ret.data.query.oauth_signature, "
<br />",

...

Panel

     "oauth_signature_method: ", ret.data.query.oauth_signature_method, "
<br />",

...

Panel

     "oauth_timestamp: ", ret.data.query.oauth_timestamp, "
<br />",

...

Panel

     "oauth_token: ", ret.data.query.oauth_token, "
<br />",

...

Panel

     "opensocial_appid: ", ret.data.query.opensocial_appid, "
<br />",

...

Panel

     "opensocial_ownerid: ", ret.data.query.opensocial_ownerid, "
<br />",

...

Panel
Panel

     "xoauth_signature_publickey: ", ret.data.query.xoauth_signature_publickey ].join("");

 
   output(html);
Panel

};


 
 };
 
makeSignedRequest();

...


Server side code

The following code shows the server side code for fetchme.php. This code relies on OAuth.php (revision 526) from the open source OAuth library project.

...

This example is not meant to be production quality code - merely a demonstration of the steps you would take to validate a signed request server-side. You should not be inlining orkut's public key certificate in your production code.

<source lang="php">

Panel
Code Block

<?php


   require_once("OAuth.php");
class OrkutSignatureMethod extends

 
   class OrkutSignatureMethod extends OAuthSignatureMethod_RSA_SHA1
{
protected function
 {
     protected function fetch_public_cert(&$request)
{
return <<<EOD
 {
       return <<<EOD
 -----BEGIN CERTIFICATE-----


 MIIDHDCCAoWgAwIBAgIJAMbTCksqLiWeMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV


 BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIG


 A1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlh


 bjAeFw0wODAxMDgxOTE1MjdaFw0wOTAxMDcxOTE1MjdaMGgxCzAJBgNVBAYTAlVT


 MQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChML


 R29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlhbjCBnzAN


 BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAseBXZ4NDhm24nX3sJRiZJhvy9eDZX12G


 j4HWAMmhAcnm2iBgYpAigwhVHtOs+ZIUIdzQHvHeNd0ydc1Jg8e+C+Mlzo38OvaG


 D3qwvzJ0LNn7L80c0XVrvEALdD9zrO+0XSZpTK9PJrl2W59lZlJFUk3pV+jFR8NY


 eB/fto7AVtECAwEAAaOBzTCByjAdBgNVHQ4EFgQUv7TZGZaI+FifzjpTVjtPHSvb


 XqUwgZoGA1UdIwSBkjCBj4AUv7TZGZaI+FifzjpTVjtPHSvbXqWhbKRqMGgxCzAJ


 BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU


 MBIGA1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVs


 cnlhboIJAMbTCksqLiWeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA


 CETnhlEnCJVDXoEtSSwUBLP/147sqiu9a4TNqchTHJObwTwDPUMaU6XIs2OTMmFu


 GeIYpkHXzTa9Q6IKlc7Bt2xkSeY3siRWCxvZekMxPvv7YTcnaVlZzHrVfAzqNsTG


 P3J//C0j+8JWg6G+zuo5k7pNRKDY76GxxHPYamdLfwk=


 -----END CERTIFICATE-----


 EOD;

}
}
Panel

     }
   }
 
   //Build a request object from the current request


   $request = OAuthRequest::from_request(null, null, array_merge($_GET, $_POST));
Panel

 
   //Initialize the new signature method


   $signature_method = new OrkutSignatureMethod();
Panel

 
   //Check the request signature


   @$signature_valid = $signature_method->check_signature($request, null, null, $_GET["oauth_signature"]);
Panel

 
   //Build the output object


   $payload = array();


   if ($signature_valid
h1.
 == true)
{
$payload
 {
     $payload["validated"] = "Success! The data was validated";


   } else
{
$payload
 {
     $payload["validated"] = "This request was spoofed";

}
Panel

   }
 
   //Add extra parameters to help debugging


   $payload["query"] = array_merge($_GET, $_POST);


   $payload["rawpost"] = file_get_contents("php://input");
Panel

 
   //Return the response as JSON


   print(json_encode($payload));

</source>

Results

When you run the client side script against the server code, the "response" function will be called with one of the following objects:

If the request was validated:

<source lang="javascript">

{
Panel
Code Block
javascript
javascript

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


   "query" : { <all of the parameters passed in the query> }

}

...


 }

If the request was not validated:

<source lang="javascript">

{
Panel
Code Block
javascript
javascript

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


   "query" : { <all of the parameters passed in the query> }

}

...


 }

Response prints this out in the following format:

Code Blockpanel
javascript
javascript
Panel

Success! The data was validated


oauth_consumer_key: orkut.com


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
Java h1. h2. Client side code

<source lang="xml">


Java

Client Side code

Code Block
xml
xml

<?xml version="1.0" encoding="UTF-8"?>

<Module>
<ModulePrefs

 <Module>
  <ModulePrefs title="oAuth Java Example">


    <Require feature="opensocial-0.7"></Require>


    <Require feature="dynamic-height"></Require>


  </ModulePrefs>


  <Content type="html">


   <![CDATA[


    <script type="text/javascript">

var

      var servletUrl="http://oauthtest.s42.eatj.com/oauth/SignedFetchVerifyServlet";
Panel
function

 
      function response(data)
{
 {
        document.getElementById('dom_handle').innerHTML=data.text;

};
Panel
function

      };
 
      function request()
{
var
 {
        var params={};

params

        params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;


        gadgets.io.makeRequest(servletUrl,response,params);

};
Panel

      };
 
      gadgets.util.registerOnLoadHandler(request);

 
    </script>
Panel
<div

 
    <div id="dom_handle"></div>


   ]]>


   </Content>


 </Module>

...


Server side code

The code implements these steps:

...

This example is not meant to be production quality code - merely a demonstration of the steps you would take to validate a signed request server-side. You should not be inlining orkut's public key certificate in your production code.<source lang="java">
package

Code Block

package net.oauth.example.provider.servlets;

...

Panel
import

 
 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;

...

Panel

 import java.io.IOException;


 import java.util.Map;


 import java.io.PrintWriter;


 import java.util.List;

 
 import javax.servlet.ServletException;

...

Panel

 import javax.servlet.http.HttpServlet;


 import javax.servlet.http.HttpServletRequest;


 import javax.servlet.http.HttpServletResponse;

 
 public class SignedFetchVerifyServlet extends HttpServlet

...

Panel
private final static String CERTIFICATE =
 {
 
   private final static String CERTIFICATE =
       "-----BEGIN CERTIFICATE-----\n"

+

           + "MIIDHDCCAoWgAwIBAgIJAMbTCksqLiWeMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV\n"

+

           + "BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIG\n"

+

           + "A1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlh\n"

+

           + "bjAeFw0wODAxMDgxOTE1MjdaFw0wOTAxMDcxOTE1MjdaMGgxCzAJBgNVBAYTAlVT\n"

+ "MQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChML\n"
+

           + "MQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChML\n"
           + "R29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlhbjCBnzAN\n"

+

           + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAseBXZ4NDhm24nX3sJRiZJhvy9eDZX12G\n"

+

           + "j4HWAMmhAcnm2iBgYpAigwhVHtOs+ZIUIdzQHvHeNd0ydc1Jg8e+C+Mlzo38OvaG\n"

+

           + "D3qwvzJ0LNn7L80c0XVrvEALdD9zrO+0XSZpTK9PJrl2W59lZlJFUk3pV+jFR8NY\n"

+

           + "eB/fto7AVtECAwEAAaOBzTCByjAdBgNVHQ4EFgQUv7TZGZaI+FifzjpTVjtPHSvb\n"

+ "

           + "XqUwgZoGA1UdIwSBkjCBj4AUv7TZGZaI+FifzjpTVjtPHSvbXqWhbKRqMGgxCzAJ\n"

+

           + "BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU\n"

+

           + "MBIGA1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVs\n"

+

           + "cnlhboIJAMbTCksqLiWeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA\n"

+

           + "CETnhlEnCJVDXoEtSSwUBLP/147sqiu9a4TNqchTHJObwTwDPUMaU6XIs2OTMmFu\n"

+

           + "GeIYpkHXzTa9Q6IKlc7Bt2xkSeY3siRWCxvZekMxPvv7YTcnaVlZzHrVfAzqNsTG\n"

+ "P3J

           + "P3J//C0j+8JWg6G+zuo5k7pNRKDY76GxxHPYamdLfwk=\n"

+ "

           + "-----END CERTIFICATE-----";

@Override

Panel
protected void

 
   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp)

throws

       throws ServletException, IOException
{
 {
     verifyFetch(req, resp);

}
Panel
@Override
protected void

   }
 
 
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp)

throws

       throws ServletException, IOException
{
 {
     verifyFetch(req, resp);

}
Panel
private void

   }
 
 
   private void verifyFetch(HttpServletRequest request, HttpServletResponse resp)

throws

       throws IOException, ServletException
{
 {
     resp.setContentType("text/html; charset=UTF-8");

PrintWriter out =

     PrintWriter out = resp.getWriter();
try {
OAuthServiceProvider provider =
new

 
     try {
       OAuthServiceProvider provider =
           new OAuthServiceProvider(null, null, null);

OAuthConsumer consumer =
new

       OAuthConsumer consumer =
           new OAuthConsumer(null, "orkut.com", null, provider);


       consumer.setProperty(RSA_SHA1.X509_CERTIFICATE, CERTIFICATE);
String method =

 
       String method = request.getMethod();

String requestUrl =

       String requestUrl = getRequestUrl(request);


       List<OAuth.Parameter> requestParameters = getRequestParameters(request);

OAuthMessage message =

Panel
new

 
       OAuthMessage message =
           new OAuthMessage(method, requestUrl, requestParameters);

...


 
       OAuthAccessor accessor = new OAuthAccessor(consumer);

...

Panel

       out.print("*** OAuthMessage Params:");


       out.print("

...

<br>URL: " + OAuthServlet.htmlEncode(message.URL));

...

Panel
for

       for (java.util.Map.Entry param : message.getParameters())
{
String key =
 {
         String key = param.getKey().toString();

String value =

         String value = param.getValue().toString();


         out.print("
<br>");

...

Panel

         out.print("Param Name-->" + OAuthServlet.htmlEncode(key));


         out.print("
 
&nbsp;");

out

         out.print("Value-->" + OAuthServlet.htmlEncode(value));

}

       }
       out.print("
<br>");

...

Panel

       out.print(" VALIDATING SIGNATURE ");


       out.print("
<br>");

...

Panel

       message.validateMessage( accessor, new SimpleOAuthValidator());


       out.print("REQUEST STATUS::OK");


       out.print("
<br>");

...

Panel
} catch

     } catch (OAuthProblemException ope)
{
 {
       out.print("
<br>");

...

Panel

       out.print("OAuthProblemException-->"

+

           + OAuthServlet.htmlEncode(ope.getProblem()));

} catch

      } catch (Exception e)
{
 {
     	 out.println(e);


     	 System.out.println(e);

throw new

       throw new ServletException(e);

} finally {

     } finally {
       out.flush();

}
}

/**

Panel
  • 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();
  •    
         }
       }
     
       /**
         * 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);

    ...

    Panel
    
         requestUrl.append("://");

    
         requestUrl.append(request.getServerName());

    ...

    
     
         if ((scheme.equals("http") && port != 80)

    ...

    Panel
    
                 || (scheme.equals("https") && port != 443))
    {
     {
           requestUrl.append(":");

    
           requestUrl.append(port);

    }
    
         }
     
         requestUrl.append(request.getContextPath());

    ...

    Panel
    
         requestUrl.append(request.getServletPath());

    ...

    
     
         return requestUrl.toString();

    ...

    Panel

    }

    /**

    ...

    List<OAuth.Parameter> parameters = new ArrayList<OAuth.Parameter>();

    Panel
    for (Object e :
    
       }
     
       /**
        * 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<OAuth.Parameter> getRequestParameters(
           HttpServletRequest request) {
     
         List<OAuth.Parameter> parameters = new ArrayList<OAuth.Parameter>();
     
         for (Object e : request.getParameterMap().entrySet())
    {
     {
           Map.Entry<String,
    String)_ entry =
     String[]> entry = (Map.
    Entry_String
    Entry<String, String
    (
    []>) e;

    ...

    
     
           for (String value : entry.getValue())

    ...

    Panel
     {
             parameters.add(new OAuth.Parameter(entry.getKey(), value));

    }
    }

    return parameters;

    Panel

    }
    }

    </source>

    
           }
         }
     
         return parameters;
       }
     }
    

    Results

    When you run the client side script against the server code, and if the request was validated:

    Panelcode
    
    *** OAuthMessage Params:

    
    URL: http://oauthtest.s42.eatj.com/oauth/SignedFetchVerifyServlet

    
    Param Name-->oauth_consumer_key Value-->orkut.com

    
    Param Name-->oauth_nonce Value-->7fe2ce6b24e17c86

    
    Param Name-->opensocial_app_id Value-->10449685582340194994

    
    Param Name-->opensocial_viewer_id Value-->10972140642666904206

    
    Param Name-->oauth_timestamp Value-->1211519778

    
    Param Name-->opensocial_owner_id Value-->10972140642666904206

    
    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 Python h1. h2. Client side code

    Copied from http://opensocial.dachary.org/signed-python-test.xml

    <source lang="xml">
    <?xml version="1.0" encoding="UTF-8" ?>
    <Module>

    Panel
    <ModulePrefs title="Python Debug Server makeRequest" height="300" />
    <Content type="html">
    <![CDATA[
    <script language="JavaScript"
    
                                         /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
    

    Python

    Client side code

    Copied from http://opensocial.dachary.org/signed-python-test.xml

    Code Block
    xml
    xml
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <Module>
      <ModulePrefs title="Python Debug Server makeRequest" height="300" />
      <Content type="html">
         <![CDATA[
              <script language="JavaScript" type="text/javascript" src="/json2.js"></script>

    <script
    
              <script type="text/javascript">
    
    function makeSignedRequest()

    ...

    Panel
    var params =
     {
       var params = {};

    
       params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;

    
       params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;

    
       var url = "http://opensocial.dachary.org/cgi-bin/fetchme.py";

    
       gadgets.io.makeRequest(url, response, params);

    
     };
    
     
     function response(ret)

    ...

    Panel
     {
       if(window.console && window.console.log)

    
          window.console.log("ret = " + JSON.stringify(ret));

    ...

    
     
       var html = [ "<font size='-1'><b>", ret.data.validated, "</b><br /

    ...

    >\n<ul><li>",

    ...

    Panel
    
         "<b>opensocial_app_id</b>: ", ret.data.query.opensocial_app_id, "</li>\n<li>",

    
         "<b>opensocial_owner_id</b>: ", ret.data.query.opensocial_owner_id, "</li>\n<li>",

    
         "<b>opensocial_viewer_id</b>: ", ret.data.query.opensocial_viewer_id, "</li>\n<li>",

    
         "<b>oauth_consumer_key</b>: ", ret.data.query.oauth_consumer_key, "</li>\n<li>",

    
         "<b>oauth_nonce</b>: ", ret.data.query.oauth_nonce, "</li>\n<li>",

    
         "<b>oauth_signature</b>: ", ret.data.query.oauth_signature, "</li>\n<li>",

    
         "<b>oauth_signature_method</b>: ", ret.data.query.oauth_signature_method, "</li>\n<li>",

    
         "<b>oauth_timestamp</b>: ", ret.data.query.oauth_timestamp, "</li>\n<li>",

    
         "<b>oauth_token</b>: ", ret.data.query.oauth_token, "</li>\n<li>",

    
         "<b>xoauth_signature_publickey</b>: ", ret.data.query.xoauth_signature_publickey, "</li></ul></font>" ].join("");
    
     
       document.getElementById('console').innerHTML = html;

    ...

    Panel
    
     
     };
    
     
     makeSignedRequest();

    ...

    Panel
    
              </script>

    <div
    
              <div id="console">...loading...</div>

    
         ]]>

    
      </Content>
    
    </Module>

    ...

    
    

    Server side code

    This code was copied from http://opensocial.dachary.org/fetchme.py and assumes http://opensocial-python-client.googlecode.com/files/opensocial-python-client-0.3.0.tar.bz or better with http://code.google.com/p/opensocial-python-client/issues/detail?id=28 patch applied (i.e. http://opensocial-python-client.googlecode.com/issues/attachment?aid=7986458758935386828&amp;name=p1)

    A python library may be used instead of the suggested openssl command line code suggested in the boddy of the example http://code.google.com/p/kurrik-resources/source/browse/trunk/src/x509/x509.py

    <source lang="python">

    Code Block
    
    #!/usr/bin/python -u

    ...

    
     
    import hashlib

    ...

    
    import urllib

    ...

    
    import cgi

    ...

    
    import urlparse

    ...

    
    import os

    ...

    
     
    from opensocial import oauth

    ...

    
    from opensocial import simplejson

    ...

    
    from Crypto.PublicKey import RSA

    ...

    
     
    # http://shindig.opensocial.dachary.org/public.cer

    ...

    
    """

    ...

    
    -----BEGIN CERTIFICATE-----

    ...

    
    MIIDmTCCAwKgAwIBAgIJAIpuyG3wc28PMA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD

    ...

    
    VQQGEwJGUjEOMAwGA1UECBMFUGFyaXMxDjAMBgNVBAcTBVBhcmlzMRQwEgYDVQQK

    ...

    
    Ewtwb2tlcnNvdXJjZTEUMBIGA1UECxMLcG9rZXJzb3VyY2UxFDASBgNVBAMTC3Bv

    ...

    
    a2Vyc291cmNlMR8wHQYJKoZIhvcNAQkBFhBsb2ljQGRhY2hhcnkub3JnMB4XDTA5

    ...

    
    MDcwNjExMDE0MFoXDTEwMDcwNjExMDE0MFowgZAxCzAJBgNVBAYTAkZSMQ4wDAYD

    ...

    
    VQQIEwVQYXJpczEOMAwGA1UEBxMFUGFyaXMxFDASBgNVBAoTC3Bva2Vyc291cmNl

    ...

    
    MRQwEgYDVQQLEwtwb2tlcnNvdXJjZTEUMBIGA1UEAxMLcG9rZXJzb3VyY2UxHzAd

    ...

    
    BgkqhkiG9w0BCQEWEGxvaWNAZGFjaGFyeS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD

    ...

    
    gY0AMIGJAoGBAMU5jnDTaadleTmZu46hwWPw1BoMvIPAbeV/Cisy2h5Syct4ulDm

    ...

    
    AbB8+ZDM0lO74kXZK88IghGQnWGovs3OH9IGZRzeLx5DViC8qMZ3hq2KgiDbuMm/

    ...

    
    Rf31Yz4Bq9dTluyDuQQzCM1XLDcMhIdu/mGPSj6hF2vTVNOop6p7VoLFAgMBAAGj

    ...

    
    gfgwgfUwHQYDVR0OBBYEFCGh+YhwndgwJACXXaaa2cNrwzthMIHFBgNVHSMEgb0w

    ...

    
    gbqAFCGh+YhwndgwJACXXaaa2cNrwzthoYGWpIGTMIGQMQswCQYDVQQGEwJGUjEO

    ...

    
    MAwGA1UECBMFUGFyaXMxDjAMBgNVBAcTBVBhcmlzMRQwEgYDVQQKEwtwb2tlcnNv

    ...

    
    dXJjZTEUMBIGA1UECxMLcG9rZXJzb3VyY2UxFDASBgNVBAMTC3Bva2Vyc291cmNl

    ...

    
    MR8wHQYJKoZIhvcNAQkBFhBsb2ljQGRhY2hhcnkub3JnggkAim7IbfBzbw8wDAYD

    ...

    
    VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBa8M5aVuUg5strfuVznZxm7rrX

    ...

    
    acX25tvSYQ8PMrux8c8K1OPEzgRXSWTAt3mfmDVpcRPXIEQWpj+84qPpRuzc5K06

    ...

    
    X8pEgt267U78TN8nHoPg/4qlD4dSbhReEafHtk8YSFgdjsUyhV9Qd34sVP2i24xl

    ...

    
    5b6vXllgNnF+LedcMw

    ...

    ==
    -----END CERTIFICATE-----

    ...

    
    """

    ...

    
    # 
    # More information about x509 conversion to hex
    # in http://www.guyrutenberg.com/2009/01/01/extract-public-key-from-x509-certificate-as-hex/

    ...

    
    #
    #

    ...

     curl http://shindig.opensocial.dachary.org/public.cer | openssl x509 -modulus -noout | sed s/Modulus=/0x/

    ...

    
    #

    ...

    
    dachary_hex_cert = "0xC5398E70D369A765793999BB8EA1C163F0D41A0CBC83C06DE57F0A2B32DA1E52C9CB78BA50E601B07CF990CCD253BBE245D92BCF088211909D61A8BECDCE1FD206651CDE2F1E435620BCA8C67786AD8A8220DBB8C9BF45FDF5633E01ABD75396EC83B9043308CD572C370C84876EFE618F4A3EA1176BD354D3A8A7AA7B5682C5"

    ...

    
     
    # http://modules.partuza.nl/public.cer

    ...

    
    """

    ...

    
    -----BEGIN CERTIFICATE----

    ...

    -
    MIIDvzCCAyigAwIBAgIJAIqG9IruKSM7MA0GCSqGSIb3DQEBBAUAMIGcMQswCQYD

    ...

    
    VQQGEwJOTDEVMBMGA1UECBMMWnVpZCBIb2xsYW5kMRIwEAYDVQQHEwlSb3R0ZXJk

    ...

    
    YW0xEDAOBgNVBAoTB1BhcnR1emExEDAOBgNVBAsTB1BhcnR1emExHDAaBgNVBAMT

    ...

    
    E3BhcnR1emEuY2hhYm90Yy5jb20xIDAeBgkqhkiG9w0BCQEWEWNoYWJvdGNAeHM0

    ...

    
    YWxsLm5sMB4XDTA4MDUxNTE1NTcyMVoXDTA5MDUxNTE1NTcyMVowgZwxCzAJBgNV

    ...

    
    BAYTAk5MMRUwEwYDVQQIEwxadWlkIEhvbGxhbmQxEjAQBgNVBAcTCVJvdHRlcmRh

    ...

    
    bTEQMA4GA1UEChMHUGFydHV6YTEQMA4GA1UECxMHUGFydHV6YTEcMBoGA1UEAxMT

    ...

    
    cGFydHV6YS5jaGFib3RjLmNvbTEgMB4GCSqGSIb3DQEJARYRY2hhYm90Y0B4czRh

    ...

    
    bGwubmwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALCupxFumTIbkEZUm/cb

    ...

    
    j1XtE0+mhqwy+i4inOtPFFvsloA9GJf0CpaFOhLgt6XDRymGqkFHS+Ul1r4Kyzdv

    ...

    
    jdNXlkC7DhcWNkO9gtOxTN89h1UXUTLYO+Ps7QLQks4BC1nGyw6RICYT+ommI77x

    ...

    
    SiMmNBH4AZTe3fhrxX2Es+6VAgMBAAGjggEFMIIBATAdBgNVHQ4EFgQUUQvfhRl0

    ...

    
    bqQGMPSYWLsk6NzTM9swgdEGA1UdIwSByTCBxoAUUQvfhRl0bqQGMPSYWLsk6NzT

    ...

    
    M9uhgaKkgZ8wgZwxCzAJBgNVBAYTAk5MMRUwEwYDVQQIEwxadWlkIEhvbGxhbmQx

    ...

    
    EjAQBgNVBAcTCVJvdHRlcmRhbTEQMA4GA1UEChMHUGFydHV6YTEQMA4GA1UECxMH

    ...

    
    UGFydHV6YTEcMBoGA1UEAxMTcGFydHV6YS5jaGFib3RjLmNvbTEgMB4GCSqGSIb3

    ...

    
    DQEJARYRY2hhYm90Y0B4czRhbGwubmyCCQCKhvSK7ikjOzAMBgNVHRMEBTADAQH/

    ...

    
    MA0GCSqGSIb3DQEBBAUAA4GBAH7YvtrOU8WlD1DDW/zcI6usZgYt/VR9wXOCYpbG

    ...

    
    4KWHXH242EWnRxO73aB5FfILTE1TBP5AFdpous47Fg41SSnjy5x0MtHCp61/w9gH

    ...

    
    22k1Qm2uZEGzSxZLun2dyGBcFNKu7nC675P1FDjO/ITAFs/r8SOnmUa22Wa/vrUf

    ...

    
    zvN/

    ...

    
    -----END CERTIFICATE-----

    ...

    
    """

    ...

    
    #
    #

    ...

     curl http://modules.partuza.nl/public.cer | openssl x509 -modulus -noout | sed s/Modulus=/0x/

    ...

    
    #

    ...

    
    partuza_hex_cert = "0xB0AEA7116E99321B9046549BF71B8F55ED134FA686AC32FA2E229CEB4F145BEC96803D1897F40A96853A12E0B7A5C3472986AA41474BE525D6BE0ACB376F8DD3579640BB0E17163643BD82D3B14CDF3D8755175132D83BE3ECED02D092CE010B59C6CB0E91202613FA89A623BEF14A23263411F80194DEDDF86BC57D84B3EE95"

    ...

    
     
    url2cert =

    ...

    Panel
     {
        'http://modules.partuza.nl/public.cer': partuza_hex_cert,

    
        'http://shindig.opensocial.dachary.org/public.cer': dachary_hex_cert
    
    }

    ...

    
     
    print "Content-Type: text/plain\n\n"

    ...

    
     
    url = 'http://' + (os.environ.get('HTTP_X_FORWARDED_SERVER') or os.environ.get('HTTP_HOST', 'localhost')) + os.environ.get('REQUEST_URI', '/')

    ...

    
    oauth_request = oauth.OAuthRequest.from_request(os.environ.get('REQUEST_METHOD', 'GET'), url)

    ...

    
    signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1()

    ...

    
    key, raw = signature_method.build_signature_base_string(oauth_request, oauth.OAuthConsumer('key', 'secret'), None)

    ...

    
     
    local_hash = hashlib.sha1(raw).digest()

    ...

    
     
    qs = cgi.parse_qs(urlparse.urlparse(url)[4])

    ...

    
    oauth_request.parameters['oauth_signature'] = urllib.unquote(qs["oauth_signature"][0])

    ...

    
    signature = oauth_request.parameters['oauth_signature'].decode('base64')

    ...

    
     
    cert_url = urllib.unquote(qs.get('xoauth_signature_publickey', ['xoauth_signature_publickey missing from QUERY_STRING'])[0])

    ...

    
     
    info = {}

    ...

    
    info['query'] = oauth_request.parameters

    ...

    
    info['url'] = url

    ...

    
     
    if cert_url in url2cert:

    ...

    Panel
    Panel
    
        hex_cert = url2cert[cert_url

    exponent = 65537

    ]
     
        exponent = 65537
        public_key_long = long(hex_cert, 16)

    
        public_key = RSA.construct((public_key_long, exponent))
    
     
        remote_hash = public_key.encrypt(signature, '')[0][-20

    ...

    Panel
    if
    :]
     
        if local_hash
    h1.
     == remote_hash:

    info
    
            info['validated'] = 'verified '

    
        else:

    info
    
            info['validated'] = 'not verified '
    
    else:

    ...

    Panel
    info
    
        info['validated'] = cert_url + ' is not among the known cert urls (' + str(url2cert.keys()) + ') '
    
    info['validated'] +=  raw + ' from URL ' + url

    ...

    
     
    print simplejson.dumps(info)

    ...

    
     
    # will run and *not* validate
    # REQUEST_URI='/foo?oauth_signature=YWJjCg==&xoauth_signature_publickey=http://shindig.opensocial.dachary.org/public.cer' fetchme.py
    

    ...

    C#

    Server side code

    This code relies on the csharp OAuth library from the open source OAuth library project.

    This example is not meant to be production quality code - merely a demonstration of the steps you would take to validate a signed request server-side. You should not be inlining orkut's public key certificate in your production code.<source lang="csharp">

    Code Block
    
    // -----------------------------------------------------------------------------------

    ...

    
    //

    ...

    
    //  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

    ...

    Panel
    HttpContext htp;
    public
    
    {
      HttpContext htp;
      public oBasePage(HttpContext _htp)

    {
    htp =
    
      {
        htp = _htp;

    }

    ...

    
      }
     
      public bool isvalidrequest()

    ...

    Panel
    {
    
      {
        //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();

    ...

    Panel
    
        cert.Import(Encoding.ASCII.GetBytes(

    @"
    
            @"-----BEGIN CERTIFICATE-----

    MIIDHDCCAoWgAwIBAgIJAMbTCksqLiWeMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
    BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIG
    A1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlh
    bjAeFw0wODAxMDgxOTE1MjdaFw0wOTAxMDcxOTE1MjdaMGgxCzAJBgNVBAYTAlVT
    MQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChML
    R29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlhbjCBnzAN
    BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAseBXZ4NDhm24nX3sJRiZJhvy9eDZX12G
    j4HWAMmhAcnm2iBgYpAigwhVHtOs+ZIUIdzQHvHeNd0ydc1Jg8e+C+Mlzo38OvaG
    D3qwvzJ0LNn7L80c0XVrvEALdD9zrO+0XSZpTK9PJrl2W59lZlJFUk3pV+jFR8NY
    eB/fto7AVtECAwEAAaOBzTCByjAdBgNVHQ4EFgQUv7TZGZaI+FifzjpTVjtPHSvb
    XqUwgZoGA1UdIwSBkjCBj4AUv7TZGZaI+FifzjpTVjtPHSvbXqWhbKRqMGgxCzAJ
    BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU
    MBIGA1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVs
    cnlhboIJAMbTCksqLiWeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA
    CETnhlEnCJVDXoEtSSwUBLP/147sqiu9a4TNqchTHJObwTwDPUMaU6XIs2OTMmFu
    GeIYpkHXzTa9Q6IKlc7Bt2xkSeY3siRWCxvZekMxPvv7YTcnaVlZzHrVfAzqNsTG
    
            MIIDHDCCAoWgAwIBAgIJAMbTCksqLiWeMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
            BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIG
            A1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlh
            bjAeFw0wODAxMDgxOTE1MjdaFw0wOTAxMDcxOTE1MjdaMGgxCzAJBgNVBAYTAlVT
            MQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChML
            R29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVscnlhbjCBnzAN
            BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAseBXZ4NDhm24nX3sJRiZJhvy9eDZX12G
            j4HWAMmhAcnm2iBgYpAigwhVHtOs+ZIUIdzQHvHeNd0ydc1Jg8e+C+Mlzo38OvaG
            D3qwvzJ0LNn7L80c0XVrvEALdD9zrO+0XSZpTK9PJrl2W59lZlJFUk3pV+jFR8NY
            eB/fto7AVtECAwEAAaOBzTCByjAdBgNVHQ4EFgQUv7TZGZaI+FifzjpTVjtPHSvb
            XqUwgZoGA1UdIwSBkjCBj4AUv7TZGZaI+FifzjpTVjtPHSvbXqWhbKRqMGgxCzAJ
            BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU
            MBIGA1UEChMLR29vZ2xlIEluYy4xDjAMBgNVBAsTBU9ya3V0MQ4wDAYDVQQDEwVs
            cnlhboIJAMbTCksqLiWeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA
            CETnhlEnCJVDXoEtSSwUBLP/147sqiu9a4TNqchTHJObwTwDPUMaU6XIs2OTMmFu
            GeIYpkHXzTa9Q6IKlc7Bt2xkSeY3siRWCxvZekMxPvv7YTcnaVlZzHrVfAzqNsTG
            P3J//C0j+8JWg6G+zuo5k7pNRKDY76GxxHPYamdLfwk=

    
            -----END CERTIFICATE-----"));
    
     
        //Getting Post

    ...

    Panel
    string
     variables
        string http_params;

    
        NameValueCollection _p = htp.Request.Form;

    
        Hashtable _hp = new Hashtable();

    ...

    
     
        foreach (string k in _p.Keys)

    ...

    Panel

    {
    if (k != null)
    {
    _hpk = _pk;
    }
    }

    ...

    
        {
          if (k != null)
          {
            _hp[k] = _p[k];
          }
        }
     
        SortedList _ps = new SortedList((IDictionary)_hp);

    ...

    Panel
    string) pairs1 = new string(
    
     
        string[] pairs1 = new string[_ps.Count];

    
        int l = 0;

    ...

    
     
        foreach (string name in _ps.Keys)

    ...

    Panel
    {
    pairs1
    
        {
          pairs1[l++] = name + "=" + Uri.EscapeDataString(_ps[name].ToString());

    }
    
        }
        http_params = String.Join("&", pairs1);

    ...

    
     
        if (_ps.Count != 0)

    ...

    Panel
    {
    
        {
          http_params = "&" + http_params;

    }
    
        }
     
        /* RSACryptoServiceProvider Provider = CertUtil.GetCertPublicKey(Cert); // if importing the file directly...

    ...

    Panel

    RSACryptoServiceProvider Provider = (RSACryptoServiceProvider)cert.PublicKey.Key;
    OAuth.OAuthBase ba = new OAuthBase();

    string signature = htp.Request.QueryString"oauth_signature";

    Panel

    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);

    Panel
    byte[] bstring =
     */
        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"]);
    Panel
    return
    
     
        return Provider.VerifyData(bstring, "SHA1", sign);

    
      }
    
    }
    

    </source>If you have any comments or questions about this page, please discuss them in the OpenSocial developer forum.</html>