OpenID+OAuth for YouTube using openid4java
Asked Answered
M

1

1

My application allows users to log in using OpenID from Google or Yahoo. There's also a feature which allows users to upload to YouTube. Some users arrive via a YouTube context with the purpose of creating something and uploading to YouTube. These users will need to authorize my application to access both the address on their Google Account via OpenID, and their YouTube account via OAuth. I'd like this to be achieved with a single authorization click for the user.

I've seen this done here: http://www.youtube.com/create/Xtranormal. The request sent to the Google OpenID endpoint from this app is:

https://accounts.google.com/o/openid2/auth?
openid.ns=http://specs.openid.net/auth/2.0&
openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&
openid.identity=http://specs.openid.net/auth/2.0/identifier_select&
openid.return_to=http://www.xtranormal.com/social/openid/complete/?next%3Dhttp%253A%252F%252Fyoutube.xtranormal.com%252Fytmm%252Fauth_popup_done%252F%26janrain_nonce%3D2011-08-29T16%253A35%253A53ZW0VqRw&
openid.assoc_handle=AOQobUcMlV0Hmk431QROK27UegIYqYffiPeCuZ8gsB2x5ULYP0FXuoDZ&
openid.ax.mode=fetch_request&
openid.ax.required=ext0,ext1,ext2&
openid.ax.type.ext0=http://axschema.org/namePerson/first&
openid.ax.type.ext1=http://axschema.org/namePerson/last&
openid.ax.type.ext2=http://axschema.org/contact/email&
openid.mode=checkid_setup&
openid.ns.ax=http://openid.net/srv/ax/1.0&
openid.ns.oauth=http://specs.openid.net/extensions/oauth/1.0&
openid.ns.sreg=http://openid.net/extensions/sreg/1.1&
openid.oauth.consumer=www.xtranormal.com&
openid.oauth.scope=http://gdata.youtube.com/&
openid.realm=http://www.xtranormal.com/&
openid.sreg.optional=postcode,country,nickname,email,fullname 

All the other OpenID support on the application (which works well), is written with OpenID4Java. I've tried to create a similar request by implementing the tips in This answer, however, I can't for the life of me get the Google popup to ask me for YouTube, it only asks for the email address.

I'm adding the parameters from the answer by adding this message extension:

public class OAuthHybridRequest implements MessageExtension{
    public static String SCOPE_YOUTUBE = "http://gdata.youtube.com/";
    ParameterList parameters;
    public OAuthHybridRequest(String scope){
        parameters = new ParameterList();
        parameters.set(new Parameter("consumer", DeploymentProperties.getDeploymentProperty("OAUTH_CONSUMER_KEY")));
        parameters.set(new Parameter("scope", scope));
    }   
    public ParameterList getParameters() {
        return parameters;
    }
    public String getTypeUri() {
        return "http://specs.openid.net/extensions/oauth/1.0";
    }
    ...
}

Which makes my request look like this:

https://accounts.google.com/o/openid2/auth?
openid.ns=http://specs.openid.net/auth/2.0&
openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&
openid.identity=http://specs.openid.net/auth/2.0/identifier_select&
openid.return_to=http://martin.test.example.no/socialdelegation/hybrid/youtube/sso/auth?is_callback%3Dtrue%26requestedURL%3D%252Fmovieeditor%252Fscripts%252Fpopupcloser.jsp&
openid.realm=http://martin.test.example.no&
openid.assoc_handle=AOQobUcMkuyp1pVZjpF-b8dVqTfB6Y6IyOZxihsk-XD1DOq0xv06lrlPgaJEF-ITUCdJiXPi&
openid.mode=checkid_setup&
openid.ns.ext1=http://specs.openid.net/extensions/oauth/1.0&
openid.ext1.consumer=test.example.no&
openid.ext1.scope=http://gdata.youtube.com&
openid.ns.sreg=http://openid.net/sreg/1.0&
openid.sreg.required=fullname,nickname,email&
openid.ns.ext3=http://openid.net/srv/ax/1.0&
openid.ext3.mode=fetch_request&
openid.ext3.type.email=http://axschema.org/contact/email&
openid.ext3.type.firstName=http://axschema.org/namePerson/first&
openid.ext3.type.lastName=http://axschema.org/namePerson/last&
openid.ext3.type.userName=http://axschema.org/namePerson/friendly&
openid.ext3.type.gender=http://axschema.org/person/gender&
openid.ext3.type.fullName=http://axschema.org/namePerson&
openid.ext3.required=email,firstName,lastName,userName,gender,fullName

What am I missing here?

Malebranche answered 30/8, 2011 at 9:22 Comment(0)
A
2

Download oauth ext for openid4java zip file from here (comment 8) and add classes to your project. Then:

// enable oauth ext for openid4java (do once)
Message.addExtensionFactory(OAuthMessage.class);

// add oauth extension to open-id request
AuthRequest authReq = ...;
OAuthRequest oauthRequest = OAuthRequest.createOAuthRequest();
oauthRequest.setScopes("oauth scope");
oauthRequest.setConsumer("oauth consumer key");
authReq.addExtension(oauthRequest);

// extract oauth request token from open-id response
AuthSuccess authSuccess = ...;
if (authSuccess.hasExtension(OAuthMessage.OPENID_NS_OAUTH)) {
    OAuthResponse oauthRes = (OAuthResponse) authSuccess
        .getExtension(OAuthMessage.OPENID_NS_OAUTH);
    // use this request token (without secret and verifier) and your oauth lib
    // to get oauth access token
    String oauthRequestToken = oauthRes.getRequestToken();
}
Asuncionasunder answered 30/8, 2011 at 15:54 Comment(8)
Thank you, this is great stuff, I wish I saw it sooner.. However, after implementing, the Google popup still doesn't ask me for YouTube, just the email address.. I've tried changing the realm to http://*.example.com, also to no avail. Do you have any idea why that could be?Malebranche
@OhHiThere Have you tried https://gdata.youtube.com as scope (https instead of http)? (By the way you should use space between scopes when you use multiple scopes).Asuncionasunder
Or maybe oauth ext has not really been added to openid request. Use Firefox "Tamper Data" add-on to verify your redirect and make sure oauth parameters have been added.Asuncionasunder
I've checked using chrome developer tools, and the params are there. https made no difference. :(Malebranche
Grasping straws here.. Could it be something about the account I'm using? It says no third party apps are authorized, but I have authorized and revoked YouTube permission on this account before... Could it be that even though the YouTube permission isn't listed in the dialog presented to the user, I'm still somehow getting it? Also, http://*.example.com is an okay OpenID realm to set for an OAuth consumer key of test.example.com, right? OpenID4J defaults to setting it to the exact url of the page I'm requesting from, strangelyMalebranche
Revoking just revokes a previously granted permission. Before adding oauth to openid try using oauth alone. Use Scribe and your oauth consumer key secret and let me know if you have been successful.Asuncionasunder
Turns out it's a realm issue. I've managed to get asked for YouTube as well now. Thank you so much for helpful advice along the way, and a great solution for the general case.Malebranche
@OhHiThere Nice to hear that, no problem. :)Asuncionasunder

© 2022 - 2024 — McMap. All rights reserved.