Question

I have the following situation:

I'm currently attempting to write a Metro-style application, with the ability to let the user sign in with his Google account, and the app requestion several permissions, as Userinfo.profile and Userinfo.email.

For this I'm currently using OAuthv2, and requesting the details worked out fine (after quite some effort and research).

Url used :

const string url = "https://accounts.google.com/o/oauth2/auth?" +
                   "client_id=" + clientId +
                   "&redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob" +
                   "&response_type=code" +
                   "&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email" +
                   "&access_type=offline";

Now the problem is, if I want the user to stay authenticated, I'd either have to do it by saving the token at the clientside, by the user, or find some way to log in using Google, keep the session and check if he is authenticated.

Problem is, I don't know how to perform the latter, and have no idea how to use it. At the moment, every time I open the application, the user is redirected to the google authorization page, where the whole procedure starts over and over again at each restart.

What I want to accomplish is that if a user logs in, I have some way of identifying him, and not always put a burden on him by re-requesting permissions for the given details.

I looked into OpenID, but I always get

<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<Type>http://openid.net/srv/ax/1.0</Type>
<Type>http://specs.openid.net/extensions/ui/1.0/mode/popup</Type>
<Type>http://specs.openid.net/extensions/ui/1.0/icon</Type>
<Type>http://specs.openid.net/extensions/pape/1.0</Type>
<URI>https://www.google.com/accounts/o8/ud</URI>
</Service>
</XRD>
</xrds:XRDS>

As a response on this url :

https://www.google.com/accounts/o8/id?openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.return_to=urn:ietf:wg:oauth:2.0:oob&openid.ns.ui=http://specs.openid.net/extensions/ui/1.0&openid.ns.ax=http://openid.net/srv/ax/1.0&openid.ax.mode=fetch_request&openid.ax.required=email,firstname,language,lastname,country&openid.ns.ext=http://specs.openid.net/extensions/oauth/1.0&openid.ext2.consumer=https://www.google.com/accounts/o8/ud?openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.return_to=urn:ietf:wg:oauth:2.0:oob&openid.ext2.scope=https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/userinfo.email

Am I building it wrong ?

If any suggestions, on either how to perform this 'correctly', what I'm trying to accomplish (an integration with google, allowing the user log in using google email, and only if he hasn't authorized the application, ask him to do so, plus finding a way of who he is when logging in for a second+ time), or on how I could do it, please feel free.

Besides, by using the stripped down version of the .Net 4.5 framework, it seems I'm unable to use OpenID libraries as they rely on the full 4.5 .

*Edit* Looking at MSDN this comes up :

To support SSO, the online provider must allow you to register a redirect URI in the form ms-app://appSID, where appSID is the SID for your app. 

Does this mean it just isn't possible? Because at google I can only request a key for a domain with http(s):// ?

Was it helpful?

Solution

Have you looked at this? https://developers.google.com/accounts/docs/OAuth2Login

It looks like you are using the Webserver flow and are requesting offline access. This should give you a refresh token after you swap the code. Hold onto this token in your application. If you do an authorization for login as well, you'll get a token back and you can use that to get the userid of the user at Google

Your application should keep track if you have a valid refresh token for a particular user. Then use that token to get the current credentials. You can use tokeninfo enpoint to validate the token. If you have a valid token for the user, there is no need to send them through the code flow to get another refresh token.

If you use the tokeninfo endpoint, the userid field is only present if the https://www.googleapis.com/auth/userinfo.profile scope was present in the request for the access token. The value of this field is an immutable identifier for the logged-in user. Store this and you should have a durable identifier of the user.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top