Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make RetrieveUserInformation public and part of IAuthenticationProvider #156

Open
nsainaney opened this issue Nov 12, 2014 · 9 comments
Open
Assignees

Comments

@nsainaney
Copy link

OAuth 2.0 tokens are meant to be bearer tokens. In the scenario that a client side app (iOS, Android, Windows Phone) authenticates using a provider, it would be great to then send that bearer token to the server to initiate an API session over REST.

The server could then use the access token to obtain the UserInformation.

@PureKrome
Copy link
Member

Hi @nsainaney - I've done a HUGE refactor of this library for a v2.0 release.

I'm not sure exactly what you mean 😢 Can you please give me an example, so I can see if I've fixed this in my refactor?

BTW, I'm days away from putting my first (very much working) alpha nuget package up to MyGet for dogfooding.

@nsainaney
Copy link
Author

This library is great for web apps (currently using with Nancy) and I've implemented IAuthenticationCallbackProvider. Everything works great.

My web app also has a REST api which can be called from and Android or iPhone app. If the app uses Google+, Facebook etc and retrieves an accessToken (using some other library - not necessarily simpleauthentication), I would like to send that accessToken to my server (which uses simpleauthentication) to verify that the user logged in to the provider.

See https://developers.google.com/+/web/signin/client-to-server-flow

I will push my fork to nsainaney/SimpleAuthentication shortly. Perhaps you can then see what I'm trying to do.

Hope this helps. Looking forward to your refactor!

@PureKrome
Copy link
Member

Ah! so i think i got you and i think i've handled this in the refactor.

The IAuthenticatedClient interface requires an AccessToken to be set when we have a successful authentication.

In this has the Token, Secret and ExpiresOn value .. which I'm assuming can be saved and resued at any time to do subsequent calls to the provider, for other resources (such as a list of contacts or to post a message etc).

For example.
With google, to get access to YOUR user information, this is the route:

https://www.googleapis.com/plus/v1/people/me?access_token={0}

and given an access_token, I populate that value.

So I now make sure that information is available to you, in your authentication callback method (which you need to implement). Whether a person STORES the access token info - that's up to them 😄

Does this now answer your issue?

If yes, this can be tested in a day or so when I put the NuGet packs up to myget (or u can clone + compile it yourself, but that might be a PITA).

NOTE: v2.0 has breaking changes re: how to use shit. It's simple .. just different signatures. Yes - i've got docs for this . about 55% done.

@nsainaney
Copy link
Author

Not quite - but I looked at your code and it's easy to make the addition. I would add:

public interface IUserInformationProvider
{
    UserInformation RetrieveUserInformation(string accessToken);
}

// Then to BaseOAuth20Provider<TAccessTokenResult> or the new OAuth2Provider add:

public UserInformation RetrieveUserInformation(string accessToken)
{
    return RetrieveUserInformation(new AccessToken
    {
        PublicToken = accessToken
    });
}

so now the Android App can call:

https://mywebap.com/api/access?provider=facebook&accessToken=XXXXXX

to log into my api. The Nancy Module does the following:

Get["/access"] = _ =>
var provider = factory.AuthenticationProviders[_.Request.provider] as IUserInformationProvider;
if (provider != null)
{
    var userInfo = provider.RetrieveUserInformation(_.Requeset.accessToken);                
    if (userInfo != null)
        // set up cookies etc.
    else
       return new HttpResponse(HttpStatusCode.Unauthorized);
}

Hope that helps. Like I said, I'd be happy to make the changes and help test the refactor.

@PureKrome
Copy link
Member

AH! you don't want to call other services from the AP (eg. get contacts, or write to a wall, etc) you just want to refresh your current details.

to refresh, u need the access token (instead of having to do the ENTIRE song-and-authentication-dance) !

Dude - love it. I'll add this code in the next day or so. Watch this space 👍 I'll report back when i've pushed code up!

I've noticed that you're returning null if the request fails (eg. token is invalid or expires). I'll stick with that right now, instead of throwing an exception.

woot

@PureKrome PureKrome added this to the 2.0 - .NET 4.5 & Async/Await milestone Nov 13, 2014
@PureKrome PureKrome self-assigned this Nov 13, 2014
@nsainaney
Copy link
Author

Yay! Thank you!

image

@PureKrome
Copy link
Member

@nsainaney buddy - so I started coding this on the train this morning and everything is working fine.. until I had another thought about this.

Why are you using the Mobile App to get the user information from Google/Facebook, etc (via an Access Token), instead of just getting the user info from your database?

When you first authenticate, we return to you an access token (which you can store in the db, etc). At that same time you have can return the user Id .. which can then be returned to the mobile app (or some unique identifier). Then, your mobile app just needs to use that id. It's already done the auth ... so why both with access tokens and stuff, at all?

I think I'm missing a scenario/step to get some better context of this.

I totally get the code and have nearly finished that bit, but was curious about the why are we doing this? Is there a better solution already?

@nsainaney
Copy link
Author

The User Id is not secure. If the Mobile App sends me a User Id, I do not know how it got the Id. If it sends me an accessToken, I can call Facebook/Google to make sure that the token is valid, not expired and start a session on my server..

My case is the following:

Mobile App uses OAuth (song and dance) to log into Facebook - gets accessToken (doesn't bother to get user information)
Sends accessToken to my server which retrieves userInformation and starts a session for user

If you log into Facebook, you can easily get the currently logged in user's user id by doing a view source of the page. But you cannot grab the access token easily (you would have to install a certificate on the computer and decrypt the https traffic to steal the access token)

Of course, I can use any Facebook client library to retrieve user information from Facebook but I am already using your library on my server for OAuth (Because the user can log in from a web page as well).

Makes sense?

@mwpowellhtx
Copy link

I'm not sure this is the same issue, but is it possibly to request bits of user information via OAuth(2)? Such as location, name, age, things of this nature? i.e. the user consents to provide the requested bits? Thanks...

@PureKrome PureKrome removed this from the 2.0 - .NET 4.5 & Async/Await milestone Oct 17, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants