You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by Richard Wallace <rw...@thewallacepack.net> on 2008/10/03 23:02:57 UTC

Using signed authentication in a gadget

Hello,

I'm working on using Shindig to add dashboards to all of our products based
on the gadget spec.  One of the things that I am really have a hard time
coming to terms with is how to handle authorization.  The basic idea is that
we have about 6 products that could benefit from having dashboards.  We want
to use Shindig and gadgets so that a gadget written for the dashboard in one
application can be trivially embedded and displayed in other applications
dashboards.  So we are looking at having each product be both a container
and a service provider.

>From my reading so far it seems like what we really want is to use the
signed authorization (or 2 legged OAuth as outlined here <
http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html>).
I've read the specs and it seems that making the request is as simple as

var params = {};
params[gadgets.io.RequestParameters.AUTHORIZATION] =
gadgets.io.AuthorizationType.SIGNED;
gadgets.io.makeRequest(url, callback, params);

But during my spelunking through the Shindig codebase I found in
OAuthConsumerRequestAuthenticationHandler that it expects the
oauth_consumer_key, the oauth_signature and the xoauth_requestor_id to be
specified as parameters in the oauth request message.  So digging deeper I
found the auth.js with shindig.js and this comment

    // Auth token - might be injected into the gadget directly, or might
    // be on the URL (hopefully on the fragment).

So, if I want it on the URL it seems I just specify
/gadgets/ifr?url=<gadget-url>#st=<security-token> for the iframe url.  But,
how do I can't figure out how to generate the security token when rendering
the container.

And if I decide I want it directly in the gadget, how would I accomplish
that?

I hope I'm making sense, this is all a bit new but I think I'm finally
starting to catch on.

Thanks,
Rich

Re: Using signed authentication in a gadget

Posted by Brian Eaton <be...@google.com>.
On Wed, Oct 8, 2008 at 10:17 AM, Richard Wallace
<rw...@thewallacepack.net> wrote:
> RSA would be much better because
> then we once the public/private keys are generated on the consumer, we can
> point the service provider at the consumer, say "trust this app", grab the
> containers public key from a predefined url and store it on the service
> provider to verify signed requests from the consumer.

Ah ha.  That was the piece I was missing, now I understand what you're
trying to do.

Re: Using signed authentication in a gadget

Posted by Richard Wallace <rw...@thewallacepack.net>.
On Wed, Oct 8, 2008 at 9:38 AM, Brian Eaton <be...@google.com> wrote:

> On Tue, Oct 7, 2008 at 8:06 PM, Richard Wallace
> <rw...@thewallacepack.net> wrote:
> > Well that's just the short term solution for now while I'm doing testing.
> > The goal will be that the first time the application starts it generates
> the
> > keys and puts them in a persistent store to be accessed when the app is
> > restarted.
>
> Which still doesn't make much sense to me, but you know better than me
> what will work in your environment.
>

I'd like to know why it doesn't make much sense.  The main reason I want to
do it this way is to make is easier on people deploying our software.  I
don't want them to have to generate keys via openssl and then put those keys
in the right place.  They could certainly do that, but it would be much more
friendly if they didn't have to.


>
> Have a look at the OAuthStore interface in Shindig - that has
> interfaces to retrieve keys and secrets for OAuth signing.  You can
> write code there to do arbitrary work to retrieve keys.  Generating an
> HMAC key on the fly will be simpler than generating RSA keys.  Check
> out BouncyCastle if you need to use RSA.
>

I don't think the HMAC would work as well in our situation because then we'd
need to make sure the consumer (our container) and the service provider (one
of our other apps) have a shared secret.  RSA would be much better because
then we once the public/private keys are generated on the consumer, we can
point the service provider at the consumer, say "trust this app", grab the
containers public key from a predefined url and store it on the service
provider to verify signed requests from the consumer.

I'll dig and figure out the exact sequence of calls, I was more hoping
someone might have already done the leg work in figuring it out and be
willing to save me digging through the java.security, javax.crypto and
Bouncy Castle APIs to figure out exactly what I need to do.  Hopefully
shouldn't be too hard.

Thanks again,
Rich

Re: Using signed authentication in a gadget

Posted by Brian Eaton <be...@google.com>.
On Tue, Oct 7, 2008 at 8:06 PM, Richard Wallace
<rw...@thewallacepack.net> wrote:
> Well that's just the short term solution for now while I'm doing testing.
> The goal will be that the first time the application starts it generates the
> keys and puts them in a persistent store to be accessed when the app is
> restarted.

Which still doesn't make much sense to me, but you know better than me
what will work in your environment.

Have a look at the OAuthStore interface in Shindig - that has
interfaces to retrieve keys and secrets for OAuth signing.  You can
write code there to do arbitrary work to retrieve keys.  Generating an
HMAC key on the fly will be simpler than generating RSA keys.  Check
out BouncyCastle if you need to use RSA.

Re: Using signed authentication in a gadget

Posted by Richard Wallace <rw...@thewallacepack.net>.
On Tue, Oct 7, 2008 at 3:36 PM, Brian Eaton <be...@google.com> wrote:

> On Tue, Oct 7, 2008 at 3:15 PM, Richard Wallace
> <rw...@thewallacepack.net> wrote:
> > Ok that makes sense.  I see where my error was.  I was thinking the
> > OAuthConsumerRequestAuthenticationHandler was what I should be using in
> the
> > gadget renderer, but it's meant for social services providers.  Only the
> > UrlParameterAuthenticationHandler is needed for my situation.
>
> Great!
>
> > So now I've managed to get things to a point where it's trying to sign
> the
> > request but the OAuth metadata isn't available and I get this
> >
> > INFO: Using random key for OAuth client-side state encryption
> > Oct 7, 2008 2:18:35 PM
> > org.apache.shindig.gadgets.oauth.OAuthModule$OAuthStoreProvider
> > loadDefaultKey
> > WARNING: Couldn't load OAuth signing key.  To create a key, run:
> >  openssl req -newkey rsa:1024 -days 365 -nodes -x509 -keyout testkey.pem
> \
> >     -out testkey.pem -subj '/CN=mytestkey'
> >  openssl pkcs8 -in testkey.pem -out oauthkey.pem -topk8 -nocrypt -outform
> > PEM
> >
> > Then edit gadgets.properties and add these lines:
> > shindig.signing.key-file=<path-to-oauthkey.pem>
> > shindig.signing.key-name=mykey
> >
> > For now I can simply hardcode a key, but what I would like to do is have
> a
> > key generated the first time the application starts up, probably with the
> > ability for the admin to generate a new one at any time.  Anybody know
> the
> > magic java.security incantation to produce a key in Java?
>
> This doesn't sound right.  The recipient of the message needs to be
> able to verify the signature.  How are they going to do that if you
> make up random signing keys every time the server restarts?
>

Well that's just the short term solution for now while I'm doing testing.
The goal will be that the first time the application starts it generates the
keys and puts them in a persistent store to be accessed when the app is
restarted.

Thanks,
Rich

Re: Using signed authentication in a gadget

Posted by Brian Eaton <be...@google.com>.
On Tue, Oct 7, 2008 at 3:15 PM, Richard Wallace
<rw...@thewallacepack.net> wrote:
> Ok that makes sense.  I see where my error was.  I was thinking the
> OAuthConsumerRequestAuthenticationHandler was what I should be using in the
> gadget renderer, but it's meant for social services providers.  Only the
> UrlParameterAuthenticationHandler is needed for my situation.

Great!

> So now I've managed to get things to a point where it's trying to sign the
> request but the OAuth metadata isn't available and I get this
>
> INFO: Using random key for OAuth client-side state encryption
> Oct 7, 2008 2:18:35 PM
> org.apache.shindig.gadgets.oauth.OAuthModule$OAuthStoreProvider
> loadDefaultKey
> WARNING: Couldn't load OAuth signing key.  To create a key, run:
>  openssl req -newkey rsa:1024 -days 365 -nodes -x509 -keyout testkey.pem \
>     -out testkey.pem -subj '/CN=mytestkey'
>  openssl pkcs8 -in testkey.pem -out oauthkey.pem -topk8 -nocrypt -outform
> PEM
>
> Then edit gadgets.properties and add these lines:
> shindig.signing.key-file=<path-to-oauthkey.pem>
> shindig.signing.key-name=mykey
>
> For now I can simply hardcode a key, but what I would like to do is have a
> key generated the first time the application starts up, probably with the
> ability for the admin to generate a new one at any time.  Anybody know the
> magic java.security incantation to produce a key in Java?

This doesn't sound right.  The recipient of the message needs to be
able to verify the signature.  How are they going to do that if you
make up random signing keys every time the server restarts?

Cheers,
Brian

Re: Using signed authentication in a gadget

Posted by Richard Wallace <rw...@thewallacepack.net>.
On Tue, Oct 7, 2008 at 12:02 PM, Brian Eaton <be...@google.com> wrote:

> On Fri, Oct 3, 2008 at 2:02 PM, Richard Wallace
> <rw...@thewallacepack.net> wrote:
> > From my reading so far it seems like what we really want is to use the
> > signed authorization (or 2 legged OAuth as outlined here <
> >
> http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html
> >).
>
> That's not what Shindig implements, Shindig implements the opensocial
> spec:
> http://code.google.com/apis/gadgets/docs/reference/#gadgets.io.makeRequest
>
> Note the "opensocial_app_url", "opensocial_owner_id" and
> "opensocial_viewer_id" parameters.
>
> > I've read the specs and it seems that making the request is as simple as
> >
> > var params = {};
> > params[gadgets.io.RequestParameters.AUTHORIZATION] =
> > gadgets.io.AuthorizationType.SIGNED;
> > gadgets.io.makeRequest(url, callback, params);
>
> Yes, that's correct.
>
> > But during my spelunking through the Shindig codebase I found in
> > OAuthConsumerRequestAuthenticationHandler that it expects the
> > oauth_consumer_key, the oauth_signature and the xoauth_requestor_id to be
> > specified as parameters in the oauth request message.
>
> That's used only for the social data APIs, which is not what you're
> implementing.
>
> You need to modify your server-side code to verify the signature on
> the request from Shindig, check the app url and owner/viewer ids, and
> then return the appropriate data.
>
> http://oauth.net has lots of OAuth libraries you can use to verify
> signatures.  So does
>
> http://code.google.com/p/opensocial-resources/wiki/OrkutValidatingSignedRequests
> .
>

Awesome.  That link helps a lot and explained many things for me.  It's
starting to become clearer...


>
> > So digging deeper I
> > found the auth.js with shindig.js and this comment
> >
> >    // Auth token - might be injected into the gadget directly, or might
> >    // be on the URL (hopefully on the fragment).
> >
> > So, if I want it on the URL it seems I just specify
> > /gadgets/ifr?url=<gadget-url>#st=<security-token> for the iframe url.
>  But,
> > how do I can't figure out how to generate the security token when
> rendering
> > the container.
>
> Have a look at DefaultSecurityTokenDecoder.java in Shindig.  Your
> container will generate a token and pass it on the iframe URL to your
> gadgets as the "st" parameter.  The gadget server will then verify the
> token to identify the user.
>
> Does this make sense?
>

Ok that makes sense.  I see where my error was.  I was thinking the
OAuthConsumerRequestAuthenticationHandler was what I should be using in the
gadget renderer, but it's meant for social services providers.  Only the
UrlParameterAuthenticationHandler is needed for my situation.

So now I've managed to get things to a point where it's trying to sign the
request but the OAuth metadata isn't available and I get this

INFO: Using random key for OAuth client-side state encryption
Oct 7, 2008 2:18:35 PM
org.apache.shindig.gadgets.oauth.OAuthModule$OAuthStoreProvider
loadDefaultKey
WARNING: Couldn't load OAuth signing key.  To create a key, run:
  openssl req -newkey rsa:1024 -days 365 -nodes -x509 -keyout testkey.pem \
     -out testkey.pem -subj '/CN=mytestkey'
  openssl pkcs8 -in testkey.pem -out oauthkey.pem -topk8 -nocrypt -outform
PEM

Then edit gadgets.properties and add these lines:
shindig.signing.key-file=<path-to-oauthkey.pem>
shindig.signing.key-name=mykey

For now I can simply hardcode a key, but what I would like to do is have a
key generated the first time the application starts up, probably with the
ability for the admin to generate a new one at any time.  Anybody know the
magic java.security incantation to produce a key in Java?

Re: Using signed authentication in a gadget

Posted by Brian Eaton <be...@google.com>.
On Fri, Oct 3, 2008 at 2:02 PM, Richard Wallace
<rw...@thewallacepack.net> wrote:
> From my reading so far it seems like what we really want is to use the
> signed authorization (or 2 legged OAuth as outlined here <
> http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/2/spec.html>).

That's not what Shindig implements, Shindig implements the opensocial
spec: http://code.google.com/apis/gadgets/docs/reference/#gadgets.io.makeRequest

Note the "opensocial_app_url", "opensocial_owner_id" and
"opensocial_viewer_id" parameters.

> I've read the specs and it seems that making the request is as simple as
>
> var params = {};
> params[gadgets.io.RequestParameters.AUTHORIZATION] =
> gadgets.io.AuthorizationType.SIGNED;
> gadgets.io.makeRequest(url, callback, params);

Yes, that's correct.

> But during my spelunking through the Shindig codebase I found in
> OAuthConsumerRequestAuthenticationHandler that it expects the
> oauth_consumer_key, the oauth_signature and the xoauth_requestor_id to be
> specified as parameters in the oauth request message.

That's used only for the social data APIs, which is not what you're
implementing.

You need to modify your server-side code to verify the signature on
the request from Shindig, check the app url and owner/viewer ids, and
then return the appropriate data.

http://oauth.net has lots of OAuth libraries you can use to verify
signatures.  So does
http://code.google.com/p/opensocial-resources/wiki/OrkutValidatingSignedRequests.

> So digging deeper I
> found the auth.js with shindig.js and this comment
>
>    // Auth token - might be injected into the gadget directly, or might
>    // be on the URL (hopefully on the fragment).
>
> So, if I want it on the URL it seems I just specify
> /gadgets/ifr?url=<gadget-url>#st=<security-token> for the iframe url.  But,
> how do I can't figure out how to generate the security token when rendering
> the container.

Have a look at DefaultSecurityTokenDecoder.java in Shindig.  Your
container will generate a token and pass it on the iframe URL to your
gadgets as the "st" parameter.  The gadget server will then verify the
token to identify the user.

Does this make sense?