Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceStack and FacebookAuthProvider

Tags:

servicestack

I've been working with ServiceStack and it's Auth providers. Specifically "FacebookAuthProvider". My issue here is that the service is called from an iOS app. This app already have a valid access token and i just want to pass this value to servicestack facebook authentication.

I've seen the tests on servicestack github page, but it still doesn't make sense to me.

Is it possible to pass this access token to servicestack, so the authentication skips the part where i ask for permission, since we already did the on the app?

Or am i approching this the wrong way?

like image 350
Allan Vraa Avatar asked Oct 22 '22 12:10

Allan Vraa


1 Answers

Instead of using the builtin facebook auth provider i created my own CustomFacebookAuthProvider. The reason is that the builtin version needs a browser to redirect the user to facebook for authentication and i didn't need that. I already had an access token.

So based on the official version FacebookAuthProvider.cs i created my own.

using System;
using System.Collections.Generic;
using System.Net;
using Elmah;
using Mondohunter.Backend.BusinessLogic.Interfaces;
using ServiceStack.Common.Extensions;
using ServiceStack.Common.Web;
using ServiceStack.Configuration;
using ServiceStack.ServiceInterface;
using ServiceStack.ServiceInterface.Auth;
using ServiceStack.Text;
using ServiceStack.WebHost.Endpoints;

namespace Mondohunter.Interfaces
{
    public class CustomFacebookAuthProvider : OAuthProvider
    {
        public const string Name = "facebook";
        public static string Realm = "https://graph.facebook.com/";
        public static string PreAuthUrl = "https://www.facebook.com/dialog/oauth";

        public string AppId { get; set; }
        public string AppSecret { get; set; }
        public string[] Permissions { get; set; }

        public CustomFacebookAuthProvider(IResourceManager appSettings)
            : base(appSettings, Realm, Name, "AppId", "AppSecret")
        {
            this.AppId = appSettings.GetString("oauth.facebook.AppId");
            this.AppSecret = appSettings.GetString("oauth.facebook.AppSecret");
        }

        public override object Authenticate(IServiceBase authService, IAuthSession session, Auth request)
        {
            var tokens = Init(authService, ref session, request);

            try
            {
                if (request.oauth_token.IsNullOrEmpty())
                    throw new Exception();

                tokens.AccessToken = request.oauth_token;
                session.IsAuthenticated = true;

                var json = AuthHttpGateway.DownloadFacebookUserInfo(request.oauth_token);
                var authInfo = JsonSerializer.DeserializeFromString<Dictionary<string, string>>(json);

                //Here i need to update/set userauth id to the email
                //UpdateUserAuthId(session, authInfo["email"]);

                authService.SaveSession(session, SessionExpiry);
                OnAuthenticated(authService, session, tokens, authInfo);

                //return json/xml/... response;
            }
            catch (WebException ex)
            {
                //return json/xml/... response;
            }
            catch (Exception ex)
            {
                //return json/xml/... response;
            }
        }

        protected override void LoadUserAuthInfo(AuthUserSession userSession, IOAuthTokens tokens, Dictionary<string, string> authInfo)
        {
            if (authInfo.ContainsKey("id"))
                tokens.UserId = authInfo.GetValueOrDefault("id");
            if (authInfo.ContainsKey("name"))
                tokens.DisplayName = authInfo.GetValueOrDefault("name");
            if (authInfo.ContainsKey("first_name"))
                tokens.FirstName = authInfo.GetValueOrDefault("first_name");
            if (authInfo.ContainsKey("last_name"))
                tokens.LastName = authInfo.GetValueOrDefault("last_name");
            if (authInfo.ContainsKey("email"))
                tokens.Email = authInfo.GetValueOrDefault("email");
            if (authInfo.ContainsKey("gender"))
                tokens.Gender = authInfo.GetValueOrDefault("gender");
            if (authInfo.ContainsKey("timezone"))
                tokens.TimeZone = authInfo.GetValueOrDefault("timezone");

            LoadUserOAuthProvider(userSession, tokens);
        }

        public override void LoadUserOAuthProvider(IAuthSession authSession, IOAuthTokens tokens)
        {
            var userSession = authSession as CustomUserSession;
            if (userSession == null) return;

            userSession.Email = tokens.Email ?? userSession.PrimaryEmail ?? userSession.Email;
        }
    }
}

I hope it makes sense.

like image 156
Allan Vraa Avatar answered Jan 02 '23 20:01

Allan Vraa