[aerogear-dev] OAuth2 Adapter

Karel Piwko kpiwko at redhat.com
Thu Jan 2 07:59:22 EST 2014


Looks good and works fine with FF24 and Chrome27. I was missing instruction how
to enable client access in Google Console though, so I added them here: https://github.com/lholmquist/ag-google-drive/pull/1

Other interesting fact is that FF shows "delete" text while Chrome shows
wastebin icon, I wasn't looking deeper into that though.

Karel

On Wed, 18 Dec 2013 14:45:39 -0500
Lucas Holmquist <lholmqui at redhat.com> wrote:

> i've created a new example here, https://github.com/lholmquist/ag-google-drive
> 
> that hopefully shows the flow a bit
> On Aug 29, 2013, at 2:05 PM, Lucas Holmquist <lholmqui at redhat.com> wrote:
> 
> > i did get it to work
> > On Aug 29, 2013, at 2:04 PM, Sebastien Blanc <scm.blanc at gmail.com> wrote:
> > 
> >> This update is really cool, is the pipe test flow working ?
> >> 
> >> 
> >> On Thu, Aug 29, 2013 at 7:57 PM, Lucas Holmquist <lholmqui at redhat.com>
> >> wrote: i've updated the sample again
> >> https://github.com/lholmquist/oauth2test
> >> 
> >> this time i added a pipe object and used pipe.read to see how the flow
> >> would be
> >> 
> >> 
> >> On Aug 29, 2013, at 11:55 AM, Lucas Holmquist <lholmqui at redhat.com> wrote:
> >> 
> >>> i've updated the sample app with the new flow
> >>> 
> >>> https://github.com/lholmquist/oauth2test
> >>> 
> >>> 
> >>> On Aug 29, 2013, at 9:23 AM, Lucas Holmquist <lholmqui at redhat.com> wrote:
> >>> 
> >>>> ok,  Kris had some thoughts on a better flow, so i refactored the code a
> >>>> bit and i think i like this way a bit better.  
> >>>> 
> >>>> New Flow - Client Flow - Standalone for now, possible integration with
> >>>> pipes
> >>>> 
> >>>> First Time - No Access Token stored( in localStorage )
> >>>> 
> >>>> User will create the Authorization Object stuff with settings/options
> >>>> 
> >>>> var thing = AeroGear.Authorization();
> >>>> 
> >>>> thing.add({
> >>>>     name: "coolThing",
> >>>>     settings: {
> >>>>         clientId: "12345.apps.googleusercontent.com",
> >>>>         redirectURL: "http://localhost:8000/redirector.html",
> >>>>         tokenValidationEndpoint:
> >>>> "https://www.googleapis.com/oauth2/v1/tokeninfo", authEndpoint:
> >>>> "https://accounts.google.com/o/oauth2/auth", revokeURL:
> >>>> "https://accounts.google.com/o/oauth2/revoke", scopes:
> >>>> "https://www.googleapis.com/auth/userinfo.profile", prompt: "force"
> >>>>     }
> >>>> });
> >>>> should have the ability to specify more settings, based on the spec
> >>>> 
> >>>> The user would then call some method( currently not good names are
> >>>> coming to me, maybe validate ) that takes success and error callbacks.
> >>>> 
> >>>> thing.services.coolThing.validate({
> >>>>     success: function( response ){
> >>>>         console.log( "Should be response from Validating the access
> >>>> token", response ); },
> >>>>     error: function( error ) {
> >>>>         //should contain a constructed URL for the user
> >>>>         console.log( "error", error );
> >>>>     }
> >>>> });
> >>>> Since this is the first time, the error callback will be called and will
> >>>> contain the constructed URL that the user should do the popup redirect
> >>>> dance with to get an access token.
> >>>> 
> >>>> what "dance" they do is up to the developer
> >>>> 
> >>>> Once that happens and they have the access token, they would call the
> >>>> validate method again.
> >>>> 
> >>>> this makes sure that the token they recieved is validated and will also
> >>>> return some other meta data related to the token, like refresh time.
> >>>> 
> >>>> Once the token has been validated, it will be stored in localStorage and
> >>>> would be accessable with the key of ag-oauth2-whatever_the_client_ID_is .
> >>>> 
> >>>> so in this example it would be something like:
> >>>> 
> >>>> ag-oauth2-12345.apps.googleusercontent.com
> >>>> There is one problem i can see here though. If the user has to
> >>>> applications with the same client ID but different scopes assigned, this
> >>>> would be a problem. That use case could be considered bad practice anyway
> >>>> 
> >>>> The user can then call the "callService"( yes, again, crappy name )
> >>>> method to get access to the service they want.
> >>>> 
> >>>> thing.services.coolThing.callService({
> >>>>     serviceURL: "https://www.googleapis.com/oauth2/v2/userinfo",
> >>>>     success: function( response ){
> >>>>         console.log( "Should be the response from the call", response );
> >>>>     },
> >>>>     error: function( error ) {
> >>>>         console.log( "error", error );
> >>>>     }
> >>>> });
> >>>> All these methods would have success/error callbacks.
> >>>> 
> >>>> Token Expiration
> >>>> 
> >>>> If the user makes a call to a service, using the callService method, and
> >>>> they recieve an error such as not authorized or token invalid or token
> >>>> expired, I'm thinking we send what the "contructed URL" should be,
> >>>> similar to the validate method described above.
> >>>> 
> >>>> Since this is a Client Side flow, there is no refresh token, so the
> >>>> client wouldn't be able to refresh the access token without doing the
> >>>> "dance" again.
> >>>> 
> >>>> 
> >>>> 
> >>>> 
> >>>> On Aug 27, 2013, at 1:57 PM, Lucas Holmquist <lholmqui at redhat.com> wrote:
> >>>> 
> >>>>> i've hacked together a sample app that shows sort of the flow.
> >>>>> 
> >>>>> https://github.com/lholmquist/oauth2test
> >>>>> 
> >>>>> it is still very rough
> >>>>> 
> >>>>> On Aug 27, 2013, at 12:42 PM, Bruno Oliveira <bruno at abstractj.org>
> >>>>> wrote:
> >>>>> 
> >>>>>> +1 keep it simple, please
> >>>>>> 
> >>>>>> Lucas Holmquist wrote:
> >>>>>>> 
> >>>>>>> On Aug 27, 2013, at 3:39 AM, Sebastien Blanc <scm.blanc at gmail.com
> >>>>>>> <mailto:scm.blanc at gmail.com>> wrote:
> >>>>>>> 
> >>>>>>>> Hi,
> >>>>>>>> That sounds good !
> >>>>>>>> Just one question, instead of using the callApi function couldn't we
> >>>>>>>> pass the oauth module (called 'thing' in your example) to the pipe
> >>>>>>>> directly, using the 'authenticator' setting. Behind the scene, the
> >>>>>>>> pipe manager will append the oauth token to the query or add the
> >>>>>>>> bearer header ?
> >>>>>>> 
> >>>>>>> I'm not sure if that is what this is going to do.  This is more of an
> >>>>>>> Authorization thing and i don't think it totally fits the pipeline
> >>>>>>> stuff. ( or it would make it a bit more complicated, and we want to
> >>>>>>> keep it simple )
> >>>>>>> 
> >>>>>>> 
> >>>>>>> i should probably change the method to be "authorize" instead
> >>>>>>> 
> >>>>>>>> Seb
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> On Mon, Aug 26, 2013 at 8:05 PM, Lucas Holmquist <lholmqui at redhat.com
> >>>>>>>> <mailto:lholmqui at redhat.com>> wrote:
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>        OAuth2 AeroGear Workflow - High Level
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>          Using Google api's
> >>>>>>>> 
> >>>>>>>>    /Server Side/
> >>>>>>>> 
> >>>>>>>>     1. user needs to first create an "application/project" to get an
> >>>>>>>>        api key
> >>>>>>>>     2. Then they would choose the services/api's then would like
> >>>>>>>>        there application to access
> >>>>>>>>     3. other google server related items....
> >>>>>>>> 
> >>>>>>>>    /Client Side/
> >>>>>>>> 
> >>>>>>>>     1. Create a new OAuth2 module thing
> >>>>>>>>     2. Get access token for the services would need to specify the
> >>>>>>>>        services they would like to access
> >>>>>>>>     3. validate the token
> >>>>>>>>     4. make calls to the service
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>          API
> >>>>>>>> 
> >>>>>>>>    |var thing = AerGear.OAuth2({
> >>>>>>>>                    name: googleEndPoints, //Just a Name
> >>>>>>>>                    clientID: "12345" //The client ID of the app from
> >>>>>>>> the API console settings: {
> >>>>>>>>                        permissions: "..",
> >>>>>>>>                        ...
> >>>>>>>>                    }
> >>>>>>>>                }).somecoolmodulename.googleEndPoints;
> >>>>>>>>    |
> >>>>>>>> 
> >>>>>>>>    /Settings: Multiple settings based on paramters here
> >>>>>>>>    <https://developers.google.com/accounts/docs/OAuth2UserAgent>/
> >>>>>>>> 
> >>>>>>>>    /Methods/
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>          authenticate
> >>>>>>>> 
> >>>>>>>>    this will authenticate with the server to get the access token and
> >>>>>>>>    then validate the token, once that is all good then the response
> >>>>>>>>    is returned.
> >>>>>>>> 
> >>>>>>>>    |thing.authenticate({
> >>>>>>>>        success:{},
> >>>>>>>>        error:{},
> >>>>>>>>        settings: {
> >>>>>>>>            //probably some settings here, like URL overides and such
> >>>>>>>>        }
> >>>>>>>>    });
> >>>>>>>>    |
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>          callApi
> >>>>>>>> 
> >>>>>>>>    not really a good name, but it would basically call the remote
> >>>>>>>>    api/services. we could either do a query string option or a Head
> >>>>>>>>    option
> >>>>>>>> 
> >>>>>>>>    example:
> >>>>>>>> 
> >>>>>>>>    |curl
> >>>>>>>> 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg'
> >>>>>>>> |
> >>>>>>>> 
> >>>>>>>>    or
> >>>>>>>> 
> >>>>>>>>    |curl -H "Authorization: Bearer {accessToken}"
> >>>>>>>> https://www.googleapis.com/oauth2/v1/userinfo |
> >>>>>>>> 
> >>>>>>>>    code:
> >>>>>>>> 
> >>>>>>>>    |thing.callApi({
> >>>>>>>>        service: "userinfo", //don't really like this name either
> >>>>>>>>        success:{},
> >>>>>>>>        error:{},
> >>>>>>>>        settings: {
> >>>>>>>>            ... //overridable baseURLs?
> >>>>>>>>        }
> >>>>>>>>    });
> >>>>>>>>    |
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>          revoke
> >>>>>>>> 
> >>>>>>>>    again, maybe not the best name. calls the "revoke" service, to
> >>>>>>>>    remove access to permissions
> >>>>>>>> 
> >>>>>>>>    |thing.revoke({
> >>>>>>>>        success: {},
> >>>>>>>>        error: {},
> >>>>>>>>        settings: {}
> >>>>>>>>    });
> >>>>>>>>    |
> >>>>>>>> 
> >>>>>>>>    Behind the scenes on all these calls, the "access_token" is
> >>>>>>>>    beining used and possibly refreshed for the user, so they don't
> >>>>>>>>    have to worry about it. They just need to call authenticate first.
> >>>>>>>>    Maybe we can have a refresh method if the user wants to refresh
> >>>>>>>>    the tokens themselves. this would do the token "dance"
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>    On Aug 26, 2013, at 1:35 PM, Bruno Oliveira <bruno at abstractj.org
> >>>>>>>>    <mailto:bruno at abstractj.org>> wrote:
> >>>>>>>> 
> >>>>>>>>>    +1 I think is a good start to us.
> >>>>>>>>> 
> >>>>>>>>>    Kris Borchers wrote:
> >>>>>>>>>>    I would like to see that but what you are saying makes sense. It
> >>>>>>>>>>    sounds like where I was headed with the Basic and Digest
> >>>>>>>>>>    adapters before I ran into browser security issues with headers.
> >>>>>>>>>>    I think and authorization API that basically just wraps itself
> >>>>>>>>>>    around secured endpoints works for me.
> >>>>>>>>> 
> >>>>>>>>>    -- 
> >>>>>>>>>    abstractj
> >>>>>>>>> 
> >>>>>>>>> 
> >>>>>>>>>    _______________________________________________
> >>>>>>>>>    aerogear-dev mailing list
> >>>>>>>>>    aerogear-dev at lists.jboss.org
> >>>>>>>>> <mailto:aerogear-dev at lists.jboss.org>
> >>>>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>>    _______________________________________________
> >>>>>>>>    aerogear-dev mailing list
> >>>>>>>>    aerogear-dev at lists.jboss.org <mailto:aerogear-dev at lists.jboss.org>
> >>>>>>>>    https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>>>>>>> 
> >>>>>>>> 
> >>>>>>>> _______________________________________________
> >>>>>>>> aerogear-dev mailing list
> >>>>>>>> aerogear-dev at lists.jboss.org <mailto:aerogear-dev at lists.jboss.org>
> >>>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>>>>>> 
> >>>>>>> _______________________________________________
> >>>>>>> aerogear-dev mailing list
> >>>>>>> aerogear-dev at lists.jboss.org
> >>>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>>>>> 
> >>>>>> -- 
> >>>>>> abstractj
> >>>>>> 
> >>>>>> 
> >>>>>> _______________________________________________
> >>>>>> aerogear-dev mailing list
> >>>>>> aerogear-dev at lists.jboss.org
> >>>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>>>> 
> >>>>> _______________________________________________
> >>>>> aerogear-dev mailing list
> >>>>> aerogear-dev at lists.jboss.org
> >>>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>>> 
> >>>> _______________________________________________
> >>>> aerogear-dev mailing list
> >>>> aerogear-dev at lists.jboss.org
> >>>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >>> 
> >>> _______________________________________________
> >>> aerogear-dev mailing list
> >>> aerogear-dev at lists.jboss.org
> >>> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >> 
> >> 
> >> _______________________________________________
> >> aerogear-dev mailing list
> >> aerogear-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> >> 
> >> _______________________________________________
> >> aerogear-dev mailing list
> >> aerogear-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/aerogear-dev
> > 
> > _______________________________________________
> > aerogear-dev mailing list
> > aerogear-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/aerogear-dev
> 



More information about the aerogear-dev mailing list