Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticated access to WebAPI via Facebook token from Android App

I'm trying to make my Android Application to log into my WebAPI services. I want to share my ideas in order to verify them.

If the access to WebAPI is performed via WebSite the steps are:

1- Call WebAPI method for logging in

2- WebAPI redirect client to facebook

3- Facebook login and returns a Token

4- If I use that token in the next calls I'll be authenticated as the right user.

And this works.

If the access to WebAPI is performed via Android APP, how can I get the access token? Actually I'm doing something like:

1- Contact Facebook via Login Button

2- Getting logged id to Facebook receiving a Token

3- Trying to perform WebAPI calls adding the Authentication: Bearer CODE to my calls

At that point I'm wandering..

How can my application now that I'm THAT particular user? If I perform something like

GET /API/METHOD1
Authentication: Bearer CODE

How can it knows that the CODE is me if the Android Application never told him? Does the application automatically contact Facebook in order to receive an answer like "yeah! I release that token, it is related to..."

Or I'm misunderstanding everything?

The other way I can figure it out is that I must use an "hybrid approach" like:

1- Call WebAPI (as via browser) 2- Get Redirect link to Facebook 3- Get the token

But.. At that point, how can I swith between Facebook App / Facebook Site to my Android application again?

Sorry for the mess, I'm trying to find out the logic beside this auth process.

like image 783
Ziba Leah Avatar asked Jun 12 '14 08:06

Ziba Leah


1 Answers

Ok, I think I've got it!

when WebAPI receives the Facebook Token doesn't know anything about user and authorizations. BUT, due to the token, can access to Facebook "as the caller".

By this way the application could perform something like:

  1. Android -> Facebook Login -> Get FBToken

  2. Android -> Web API -> Send FBToken

  3. Web API -> Facebook -> /me Sending FBToken

  4. Facebook -> Web API -> Identity

  5. Web API -> Andoid -> This is the token for you Identity

  6. Android -> Web API -> Give me Auth Method, Authorization: Bearer WebAPIToken

I found out a useful class online: (based on WebApi ASP.NET Identity Facebook login)

private async Task<FacebookUserViewModel> VerifyFacebookAccessToken(string accessToken)
{
    FacebookUserViewModel fbUser = null;
     var path = "https://graph.facebook.com/me?access_token=" + accessToken;
     var client = new HttpClient();
     var uri = new Uri(path);     
     var response = await client.GetAsync(uri);
     if (response.IsSuccessStatusCode)
     {
         var content = await response.Content.ReadAsStringAsync();
         fbUser = Newtonsoft.Json.JsonConvert.DeserializeObject<FacebookUserViewModel>     (content);
     }

     return fbUser;
 }


 public class FacebookUserViewModel
 {
     [JsonProperty("id")]
     public string ID { get; set; }
     [JsonProperty("first_name")]
     public string FirstName { get; set; }
     [JsonProperty("last_name")]
     public string LastName { get; set; }
     [JsonProperty("username")]
     public string Username { get; set; }
     [JsonProperty("email")]
     public string Email { get; set; }
 }

So, you could have a WebAPI like:

    [HttpGet]
    [AllowAnonymous]
    public async Task<string> GetTokenFromFacebook(string accessToken)
    {
        var user = await VerifyFacebookAccessToken(accessToken);
        //Search on your DB for the user ID or email
        //Get token for user
        return token;
    }

A complete and perfect explanation is here: http://thewayofcode.wordpress.com/2014/03/01/asp-net-webapi-identity-system-how-to-login-with-facebook-access-token/

Example of token creation

        var tokenExpirationTimeSpan = TimeSpan.FromDays(14);            
        var identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.Name, UserName, null, "Facebook"));
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.ToString(), null, "LOCAL_AUTHORITY"));
        AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
        var currentUtc = new Microsoft.Owin.Infrastructure.SystemClock().UtcNow;
        ticket.Properties.IssuedUtc = currentUtc;
        ticket.Properties.ExpiresUtc = currentUtc.Add(tokenExpirationTimeSpan);
        var accesstoken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);

I hope it helps!

like image 79
Ziba Leah Avatar answered Nov 07 '22 21:11

Ziba Leah