EzDev.org

Xamarin.Auth

Xamarin.Auth


login expiration/idle timeout for mobile apps

I am new to Xamarin and getting started on building an app. I am using XAMARIN.Auth to store the user name and the Token after login. The Auth token on the server has expiration. When the user resumes the app from the background, what is the best practice to see if they need to login or use the existing token? I am thinking of checking the token validation from service. Is that ok? And how is idle timeout implemented?


Source: (StackOverflow)

Xamarin Auth Store Keychain not working after ios10 upgrade

I'm using Xamarin.Auth (https://components.xamarin.com/view/xamarin.auth/) to store my credentials, as I've always done.

var accountStore = AccountStore.Create ();
foreach (var account in  accountStore.FindAccountsForService("myAppName"))
    accountStore.Delete (account, "myAppName");

AccountStore.Create().Save(acc, "myAppName");

After the upgrade to iOS 10 I get this error storing credentials:

"Could not save account to KeyChain: -34018"

at Xamarin.Auth.KeyChainAccountStore.Save (Xamarin.Auth.Account account,System.String serviceId) [0x000b2] in <402cf9b3716845b3bdddef581cb33a3e>:0 

Latest version installed 1.2.3.1 The problem seems to persist only on the SIMULATOR


Source: (StackOverflow)

Error while installing Xamarin.Auth on visual studio 2015 community

While installing Xamarin.Auth Nuget i am getting following error:

Severity Code Description Project File Line Suppression State Error Could not install package 'Validation 2.0.4.14103'. You are trying to install this package into a project that targets 'Xamarin.iOS,Version=v1.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author. 0


Source: (StackOverflow)

Xamarin.Auth getting disallowed_useragent error [Xamarin.Forms]

I was trying to implement login with Google and Facebook. I have successfully implemented Facebook login with Xamarin.Auth but in the Google Login I am getting error disallowed_useragent, I know Google has changed their policy and will not allow the login using WebView but is there any other way to implement Login with Google in Xamarin.Forms (Portable)?

enter image description here

Thank You.


Source: (StackOverflow)

How to use Xamarin.Forms with Xamarin.Auth to store and retrieve Account object

In a Xamarin.Forms project and I'd like to use Xamarin.Auth just to store and retrieve Account object securely. Please note that I am not taking about integrating with Facebook, Google or any other service that serves end-to-end oAuth login experience.


Source: (StackOverflow)

Xamarin.Auth with Google APIs: Renew credentials?

I'm trying to use Xamarin.Auth with the Xamarin Google-APIs to login to Google and access Drive. I've managed to get nearly everything working, but the authentication tokens seem to expire after about an hour. Everything works great for awhile, but after about an hour, when I attempt access, I get an Invalid Credentials [401] error and a leak:

Google.Apis.Requests.RequestError
Invalid Credentials [401]
Errors [
    Message[Invalid Credentials] Location[Authorization - header] Reason[authError] Domain[global]
]
: GoogleDriveAgent: FetchRemoteFileList() Failed! with Exception: {0}
[0:] Google.Apis.Requests.RequestError
Invalid Credentials [401]
Errors [
    Message[Invalid Credentials] Location[Authorization - header] Reason[authError] Domain[global]
]
: GoogleDriveAgent: FetchRemoteFileList() Failed! with Exception: {0}

objc[37488]: Object 0x7f1530c0 of class __NSDate autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[37488]: Object 0x7f151e50 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
//...more leaks.

I'd like to make sure I'm using Xamarin.Auth and the Google APIs as intended, so here is my code:

In my GoogleDriveService class, I've got an account store and a saved account:

AccountStore Store { 
    get {
        if (m_store == null)
            m_store = AccountStore.Create ();
        return m_store;
    }
}

Account SavedAccount { 
    get {
        var savedAccounts = Store.FindAccountsForService ("google");
        m_savedAccount = (savedAccounts as List<Account>).Count > 0 ? (savedAccounts as List<Account>) [0] : null;

        return m_savedAccount;
    }
}

I initialize a session and start the service:

void InitializeSession ()
{
    Authenticator = new GoogleAuthenticator (ClientID, new Uri (RedirectUrl), GoogleDriveScope);
    Authenticator.Completed += HandleAuthenticationCompletedEvents;

    if (SavedAccount != null) {
        Authenticator.Account = SavedAccount;
        StartService ();
    }

    UpdateSignInStatus ();
}

bool StartService ()
{
    try {
        Service = new DriveService (Authenticator);
        return true;
    } catch (Exception ex) {
        // Log exception
        return false;
    }
}

...and respond to authentication completed events:

void HandleAuthenticationCompletedEvents (object sender, AuthenticatorCompletedEventArgs e)
{
    if (e.IsAuthenticated) {  // Success
        UpdateSignInStatus();
        Store.Save (e.Account, "google");
        Authenticator.Account = e.Account;
        StartService();
        LoginController.DismissViewController(true, null);
    } else {                                    // Cancelled or no success
        UpdateSignInStatus();
        LoginController.DismissViewController(true, null);
        LoginController = null;
        InitializeSession ();  // Start a new session
    }
}

Again, everything works fine, for awhile, but then the authentication expires. I understand that it should, but I thought the credentials saved in the AccountStore ought to still work.

In the Xamarin.Auth getting started docs, it says that calling Save again will overwrite the credentials and that "This is convenient for services that expire the credentials stored in the account object." Sounds promising...

So I tried another approach: having an IsSignedIn property that always overwrites the credentials in the getter...

public bool IsSignedIn { 
    get {
        if (Authenticator == null) {
            m_isSignedIn = false;
            return m_isSignedIn;
        }

        if (Authenticator.Account != null) {
            Store.Save (Authenticator.Account, "google"); // refresh the account store
            Authenticator.Account = SavedAccount;
            m_isSignedIn = StartService ();
        } else {
            m_isSignedIn = false;
        }

        return m_isSignedIn;
    }
}

...and then I access IsSignedIn before any API calls (Fetching metadata, downloading, etc). It doesn't work: I'm still getting expired credentials errors shown above.

Is this a case of needing to refresh the token? What am I doing wrong?


Source: (StackOverflow)

Why is Xamarin.Auth throwing authentication error with OAuth1Authenticator and Twitter

I am currently using Xamarin.Auth on a iOS project to handle some user authentication via Facebook and Twitter in my application. The Facebook authentication using OAuth2Authenticator works great and my implementation was based mainly off the docs (http://components.xamarin.com/gettingstarted/xamarin.auth). Twitter however still uses OAuth1 it seems and thus I based my implementation mainly off the answer in this StackOverflow questions (https://stackoverflow.com/a/21982205). Everything works properly and I am able to retrieve user, tweets, etc. but after all the code executes I receive a "Authentication Error" popup on the screen saying "Object reference not set to an instance of an object." there is nothing printed to the console however as is the case with most normal errors I have seen thus far. I can dismiss the popup and everything continues to preform correctly. I believe I have narrowed the problem down to something within the OAuth1Authenticator request as I still receive the error when all of the other handling code has been commented out. Please reference the code below to see what might be the cause of this.

public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        signupBtn.TouchUpInside += delegate {
            LoginToTwitter(true, this);
        };
    }
    void LoginToTwitter(bool allowCancel, UIViewController _vc)
    {

        var auth = new OAuth1Authenticator (
            consumerKey: "My Consumer Key", 
            consumerSecret: "My Consumer Secret", 
            requestTokenUrl: new Uri("https://api.twitter.com/oauth/request_token"), 
            authorizeUrl: new Uri("https://api.twitter.com/oauth/authorize"), 
            accessTokenUrl: new Uri("https://api.twitter.com/oauth/access_token"), 
            callbackUrl: new Uri("My callback url"),
            getUsernameAsync: (IDictionary<string, string> accountProperties) => {
                string screen_name = "";
                if (accountProperties.TryGetValue("screen_name", out screen_name)) {
                    Console.WriteLine("SN: {0}", screen_name);
                    Account a = new Account(screen_name, accountProperties);
                    AuthenticatorCompletedEventArgs e = new AuthenticatorCompletedEventArgs(a);
                    TwitterCompleted(e, _vc);
                }
                return null;}
        );
        auth.AllowCancel = allowCancel;

        UIViewController authView = auth.GetUI ();

        _vc.PresentViewController (authView, true, null);
    }
    void TwitterCompleted (AuthenticatorCompletedEventArgs e, UIViewController _vc)
    {
        var theAccount = e.Account;
        var theProperties = theAccount.Properties;
        foreach (var item in theProperties) {
            Console.WriteLine (item); //debugging
        }
        InvokeOnMainThread (delegate {
            _vc.DismissViewController (true, null);
        });

        AccountStore.Create ().Save (e.Account, "Twitter");

        if (!e.IsAuthenticated) {
            Console.WriteLine("Not authorized");
            return;
        }

        theScreenName = e.Account.Properties["screen_name"];
        theCount = "2";

        IDictionary<string, string> theDict = new Dictionary<string, string>();;
        theDict.Add("screen_name", theScreenName);
        theDict.Add("count", theCount);


        var request = new OAuth1Request("GET", new Uri("https://api.twitter.com/1.1/statuses/user_timeline.json"), theDict, e.Account, false); 
        request.GetResponseAsync().ContinueWith (t => {
            if (t.IsFaulted)
                Console.WriteLine("Error: {0}", t.Exception.InnerException.Message);
            else if (t.IsCanceled)
                Console.WriteLine("Canceled");
            else
            {
                var obj = JsonValue.Parse (t.Result.GetResponseText());
                Console.WriteLine("object: {0}", obj); // debugging
            }

        }, uiScheduler);
        return;
    }
    private readonly TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Source: (StackOverflow)

Xamarin Auth - Facebook & GooglePlus

I'm currently begining to work with Xamarin.Auth and I'm facing 2 problems for which I'm stuck since 1 day and half..

I have this piece of code :

public class OAuth
{
    private Account account;
    private AccountStore store;

    // These values do not need changing
    public string Scope;
    public string AuthorizeUrl;
    public string AccessTokenUrl;
    public string UserInfoUrl;

    string clientId;
    string redirectUri;

    private Func<JObject, User> OAuthParser;

    private Action<User> OnCompleted;
    private Action<string> OnError;

    public OAuth()
    {
        account = null;
        store = null;

        Scope = "";
        AuthorizeUrl = "";
        AccessTokenUrl = "";
        UserInfoUrl = "";

        clientId = "";
        redirectUri = "";
    }

    public OAuth Facebook()
    {
        // These values do not need changing
        Scope = "public_profile";
        AuthorizeUrl = "https://m.facebook.com/dialog/oauth/";
        AccessTokenUrl = "";
        UserInfoUrl = "";

        switch (Device.RuntimePlatform)
        {
            case Device.iOS:
                clientId = "<insert IOS client ID here>";
                redirectUri = "<insert IOS redirect URL here>:/oauth2redirect";
                break;

            case Device.Android:
                clientId = "206316176526191";
                redirectUri = "http://www.facebook.com/connect/login_success.html";
                break;
        }

        OAuthParser = ParseFacebookResponse;

        return this;
    }

    public OAuth GooglePlus()
    {
        // These values do not need changing
        Scope = "https://www.googleapis.com/auth/userinfo.email";
        AuthorizeUrl = "https://accounts.google.com/o/oauth2/auth";
        AccessTokenUrl = "https://www.googleapis.com/oauth2/v4/token";
        UserInfoUrl = "https://www.googleapis.com/oauth2/v2/userinfo";

        switch (Device.RuntimePlatform)
        {
            case Device.iOS:
                clientId = "<insert IOS client ID here>";
                redirectUri = "<insert IOS redirect URL here>:/oauth2redirect";
                break;

            case Device.Android:
                clientId = "548539660999-muighch5brcrbae8r53js0ggdad5jt45.apps.googleusercontent.com";
                redirectUri = "com.googleusercontent.apps.548539660999-muighch5brcrbae8r53js0ggdad5jt45:/oauth2redirect";
                break;
        }

        OAuthParser = ParseGooglePlusResponse;

        return this;
    }

    public OAuth2Authenticator Authenticator(Action<User> onCompleted, Action<string> onError)
    {
        OAuth2Authenticator authenticator = new OAuth2Authenticator(
            clientId,
            null,
            Scope,
            new Uri(AuthorizeUrl),
            new Uri(redirectUri),
            new Uri(AccessTokenUrl),
            null,
            false);

    authenticator.Completed += OnAuthCompleted;
    authenticator.Error += OnAuthError;

        OnCompleted = onCompleted;
        OnError = onError;

        return authenticator;
    }

    private async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
    {
    OAuth2Authenticator OAuth2Authenticator = sender as OAuth2Authenticator;
    if (OAuth2Authenticator != null)
    {
        OAuth2Authenticator.Completed -= OnAuthCompleted;
        OAuth2Authenticator.Error -= OnAuthError;
    }

    //User user = null;
    if (e.IsAuthenticated)
    {
        // If the user is authenticated, request their basic user data from Google
        // UserInfoUrl = https://www.googleapis.com/oauth2/v2/userinfo
        var request = new OAuth2Request("GET", new Uri(UserInfoUrl), null, e.Account);
        var response = await request.GetResponseAsync();
        if (response != null)
        {
                // Deserialize the data and store it in the account store
                // The users email address will be used to identify data in SimpleDB
                string str = await response.GetResponseTextAsync();
                JObject jobject = JObject.Parse(str);
                User user = OAuthParser(jobject);

                OnCompleted(user);
        }

        if (account != null)
        {
            store.Delete(account, App.AppName);
        }

        await store.SaveAsync(account = e.Account, App.AppName);
    }
}

private void OnAuthError(object sender, AuthenticatorErrorEventArgs e)
{
        OAuth2Authenticator OAuth2Authenticator = sender as OAuth2Authenticator;

    if (OAuth2Authenticator != null)
    {
        OAuth2Authenticator.Completed -= OnAuthCompleted;
        OAuth2Authenticator.Error -= OnAuthError;
    }

    OnError("Authentication error: " + e.Message);
}

    private static User ParseGooglePlusResponse(JObject jobject)
    {
        try
        {
            User user = new User()
            {
                Email = jobject["email"].ToString(),
                Pseudo = jobject["name"].ToString(),
                Firstname = jobject["given_name"].ToString(),
                Surname = jobject["family_name"].ToString(),
                Image = jobject["picture"].ToString(),
                Password = "girafe"
            };
            return user;
        }
        catch (Exception e) 
        { Debug.WriteLine(e.ToString()); }
        return null;
    }

    private static User ParseFacebookResponse(JObject jobject)
    {
        try
        {
            Debug.WriteLine(jobject);
            User user = new User()
            {
                Email = jobject["email"].ToString(),
                Pseudo = jobject["name"].ToString(),
                Firstname = jobject["given_name"].ToString(),
                Surname = jobject["family_name"].ToString(),
                Image = jobject["picture"].ToString(),
                Password = "girafe"
            };
            return user;
        }
        catch (Exception e)
        { Debug.WriteLine(e.ToString()); }
        return null;
    }
}

So, I'm using this class like that:

private void FacebookAuthConnection()
    {
        AuthenticationState.Authenticator = OAuthService.Facebook().Authenticator(OAuthLoginCompleted, OAuthLoginError);
        Presenter.Login(AuthenticationState.Authenticator);
    }

However, the problems are coming.. First, GooglePlus works, but I got an alert on my android phone that says "Chrome Custom Tabs Doesn't Close ...", so the application crashes with an empty stack trace... I searched on the web and the only thing I got is to turn false the last parameter of new OAuth2Authenticator();, which doesn't work since google doesn't allow it from a webview...

So I was like, ok my code works, I get the user infos blablabla, let's try with facebook if it works from the native browser. However, I can't find the parameters URL...

Scope = "";
AuthorizeUrl = "";
AccessTokenUrl = "";
UserInfoUrl = "";
  • Scope seems to be public_profile
  • AuthorizationUrl would be https://m.facebook.com/dialog/oauth/

But what about the 2 others? I have them for Google+.

I'm really stuck and I feel like, each new seconds that passes, I get more and more frustrated...

Thank !


Edit

My actual values :

Scope = "email";
AuthorizeUrl = "https://www.facebook.com/v2.8/dialog/oauth";
AccessTokenUrl = "https://graph.facebook.com/oauth/access_token";
UserInfoUrl = "https://graph.facebook.com/me?fields=email,name,gender,picture\"";

clientId = "XXXX";
redirectUri = "http://www.facebook.com/connect/login_success.html";

Source: (StackOverflow)

Xamarin.Auth iOS9 Authentication SSL ERROR

I've just updated XCode to the 7.0 (7A220) and this take my Simulators to iOS9.

From that moment I cannot perform successfully any OAUTH call from the simulators.. I tried every model, from my App to the "sample Xamarin.Auth App".

The answer is always the same:

"Authentication Error

An SSL error has occurred and a secure connection to the server cannot be made"

Exception I get

The Code is the STANDARD one, I only changed my AppID. The same code is working on the Android version of the same App!

var auth = new OAuth2Authenticator (
            clientId: "my app id",
            scope: "",
            authorizeUrl: new Uri ("https://m.facebook.com/dialog/oauth/"),
            redirectUrl: new Uri ("http://www.facebook.com/connect/login_success.html"));

        auth.AllowCancel = allowCancel;

        // If authorization succeeds or is canceled, .Completed will be fired.
        auth.Completed += (s, e) =>
        {
            // We presented the UI, so it's up to us to dismiss it.
            dialog.DismissViewController (true, null);

            if (!e.IsAuthenticated) {
                facebookStatus.Caption = "Not authorized";
                dialog.ReloadData();
                return;
            }

            // Now that we're logged in, make a OAuth2 request to get the user's info.
            var request = new OAuth2Request ("GET", new Uri ("https://graph.facebook.com/me"), null, e.Account);
            request.GetResponseAsync().ContinueWith (t => {
                if (t.IsFaulted)
                    facebookStatus.Caption = "Error: " + t.Exception.InnerException.Message;
                else if (t.IsCanceled)
                    facebookStatus.Caption = "Canceled";
                else
                {
                    var obj = JsonValue.Parse (t.Result.GetResponseText());
                    facebookStatus.Caption = "Logged in as " + obj["name"];
                }

                dialog.ReloadData();
            }, uiScheduler);
        };

        UIViewController vc = auth.GetUI ();
        dialog.PresentViewController (vc, true, null);

The IOS9 Simulator can surf the web, so it is not a "connectivity problem". I also tried with Facebook SDK, same error. Could it be a certificate issue?

Thanks


Source: (StackOverflow)

Using Xamarin.Auth for OAuth2 authentication - username and password?

I'm facing some issue, while using Xamarin.Auth for OAuth2 authentication.

From POSTMAN I'm sending request for token, via GET method to my backend URL: http://example.com/backend/oauth/token by adding to header:

Authorization, Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

and with below parameters in URL:

client_id=backendClient

scope=read

grant_type=password

username=admin

password=admin

so it goes like: http://example.com/backend/oauth/token?client_id=backendClient&scope=read&grant_type=password&username=admin&password=admin

it gives me back JSON, which looks like:

{
"access_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"token_type": "bearer",
"refresh_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"expires_in": 9999,
"scope": "read"
}

I wanted to authenticate to my backend service, from mobile application (using Xamarin.Forms app), and I've tried to use Xamarin.Auth, for authenticating to my back-end - https://developer.xamarin.com/guides/xamarin-forms/web-services/authentication/oauth/

Indeed using OAuth2Authenticator, it's able at least to "ping" my backend (by putting URL, clientIde etc), as it returns:

<UnauthorizedException>
    <error>unauthorized</error>
    <error_description>Full authentication is required to access this resource</error_description>
</UnauthorizedException>

however message it's beeing send in wrong way - at least I think so, as there is no Authorization in header + I haven't see any possibility to pass username and password into OAuth2Authenticator.

Does anyone have idea, how I can do this? Or should I use something else - not Xamarin.Auth?

Thanks.


Source: (StackOverflow)

OAuth1Authenticator of Xamarin.Auth not terminating not completing

I am currently trying to use a REST service inside a xamarin.forms app.

To perform the authentication I use this code:

string consumerKey = "consumer_key";
string consumerSecret = "consumer_secret";
var requestTokenUrl = new Uri("https://service/oauth/request_token");
var authorizeUrl = new Uri("https://dservice/oauth/authorize");
var accessTokenUrl = new Uri("https://service/oauth/access_token");
var callbackUrl = new Uri("customprot://oauth1redirect");
authenticator = new Xamarin.Auth.OAuth1Authenticator(consumerKey, consumerSecret, requestTokenUrl, authorizeUrl, accessTokenUrl, callbackUrl, null, true);

authenticator.ShowErrors = true;
authenticator.Completed += Aut_Completed;

var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();

presenter.Completed += Presenter_Completed;
authenticator.Error += Authenticator_Error;

presenter.Login(authenticator);

Now, after authenticating the user will be redirected to customprot://oauth1redirect. To catch this redirection I added a new IntentFilter (for Android) like this:

 [Activity(Label = "OAuthLoginUrlSchemeInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
[IntentFilter(
 new[] { Intent.ActionView },
 Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
 DataSchemes = new[] { "customprot"},
 DataPathPrefix = "/oauth1redirect")]
public class OAuthLoginUrlSchemeInterceptorActivity : Activity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Convert Android.Net.Url to Uri
        var uri = new Uri(Intent.Data.ToString());

        // Load redirectUrl page
        Core.Controller.authenticator.OnPageLoading(uri);
        Core.Controller.authenticator.OnPageLoaded(uri);

        Finish();
    }
}

As far as I understood the documentation of xamarin.auth this will trigger the OAuth1Authenticator to parse the resulting url to get the authenticated user's credentials, and ultimatley triggering the Completed or Error event. But suprisingly nothing happens: no event is called or error raised. As this makes debugging harder, I do not really know how to solve this issue. Therefore, I am looking for suggestings about the cause of the issue and possible solutions, too.

Edit: Just to make this clearer: The OnCreate method of the intent is called, but executing the OnPageLoading method does not raise the Completed nor the Error event of the authenticator.

Edit2: here is the code of my callbacks (I created a breakpoint inside each of them, and the debugger does not break at them or raise an exception, so I am quite sure, that the callbacks are not called at all).

private static void Presenter_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
    throw new NotImplementedException();
}

private static void Aut_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
    throw new NotImplementedException();
}

Source: (StackOverflow)

use xamarin.auth to get refresh token for google api

 var auth = new OAuth2Authenticator(clientId: "my client id",
        scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/calendar",
        authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/auth"),
        redirectUrl: new Uri("https://www.googleapis.com/plus/v1/people/me"),
        getUsernameAsync: null);
        auth.AllowCancel = allowCancel;
        List<Event> events = new List<Event>();

        auth.Completed += async (sender, e) =>
         {
             if (!e.IsAuthenticated)
             {
                 Toast.MakeText(_activity, "Fail to authenticate!", ToastLength.Short).Show();
                 return;
             }

             string access_token;
             e.Account.Properties.TryGetValue("access_token", out access_token);

When i try to retrieve the refresh token in the same way i retreive the access token it does not work.

i am able to get the access token but not able to get the refresh token. I have tried deleting authorization from the google account because i read that you only get the refresh token the first time you grant access but i still cannot retrieve the access token. I have also read that i need to add access_type=offline and approval_prompt=force to the request but i do not know where to add it using xamarin.auth.


Source: (StackOverflow)

Xamarin.Auth: Account data not persisted when app is updated

I'm using Xamarin.Auth to authenticate with services like foursquare and so. I've gotten my authentication code working all good, the problem is that the account data is not persisted when I deploy a new version of my app - each time I deploy a test version on the phone, I've to re-authenticate.

Here's how I store the account;

  /// <summary>
/// Stores the account.
/// </summary>
private void StoreAccount(AuthenticatorCompletedEventArgs eventArgs)
{
    if (!eventArgs.IsAuthenticated) // make sure we are authenticated.
    {
        Log.Debug(Logging.AppTag, "FourSquareClient can't store account as auth. is cancelled. ");
        return;
    }

    this.IsAuthenticated = true;
    this.Account = eventArgs.Account;

    AccountStore.Create(this.OwnerContext).Save(eventArgs.Account, "Foursquare");
}

and here is how I check if we have a stored account;

 /// <summary>
/// Retrieves stored account.
/// </summary>
private void RetrieveAccount()
{
    if (this.IsAuthenticated)
    {
        Log.Debug(Logging.AppTag, "FourSquareClient is already authenticated! ");
        return;
    }


    var accounts = AccountStore.Create(this.OwnerContext).FindAccountsForService("Foursquare");
    var enumerable = accounts as IList<Account> ?? accounts.ToList();

    if (enumerable.Any())
    {
        Log.Info(Logging.AppTag, "Foursquareclient found account data.");
        this.IsAuthenticated = true;
        this.Account = enumerable.First();
    }
    else
    {
        Log.Info(Logging.AppTag, "Foursquareclient no account data found!");
        this.IsAuthenticated = false;
        this.Account = null;
    }
}

Source: (StackOverflow)

Xamarin.Auth Android project results in "Cannot find symbol" error for CustomTabs?

I am trying to implement the Xamarin.Auth library in a Xamarin.Forms project. After installing the library in my client project I received a System.NotImplementedException:

System.NotImplementedException: 

Portable Bait And Switch is nuget feature, so the package must be installed in all project. 
NotImplementedException will indicate that Portable Code from PCL is used and not Platform Specific implementation. 
Please check whether platform specific Assembly is properly installed.

Therefore, I installed the library in the Droid project as well. Once I did this, I started getting "Cannot find symbol" errors related to the CustomTabs control:

error: cannot find symbol
extends android.support.customtabs.CustomTabsCallback
symbol:   class CustomTabsCallback
location: package android.support.customtabs    Kpa.Mko.Mobile.Client.Droid
H:\...\obj\Debug\android\src\android\support\customtabs\CustomTabsClient_CustomTabsCallbackImpl.java

There are 6 of these errors in all, each one related to CustomTabs in some way.

We're using:

  • Xamarin.Auth 1.3.2.5 Xamarin.Forms 2.3.3.193
  • Xamarin.Android.Support.v7.AppCompat 25.1.1
  • Xamarin.Android.Support.v7.CardView 25.1.1
  • Xamarin.Android.Support.v7.MediaRouter 25.1.1
  • Xamarin.Android.Support.v7.RecyclerView 25.1.1

I've done some research on this problem in the Xamarin forums, here on Stack Overflow, and of course Google but none of the suggested fixes I found is solving my problem. I am completely confused as to what could be going on here. Am I missing the obvious?

Thanks!


Source: (StackOverflow)

Xamarin.Auth fails to complete with Trakt

I'm building an app as Trakt client using Xamarin. To authenticate users, I use Xamarin.Auth because its cross-platform. However, after the authentication succeeds, it doesn't call Completed event handler. The event is only called once I click on the Back button but it returns a null Account object and false IsAuthenticated. I'm wondering if its because the redirect uri is invalid.

Please see my code below.

[assembly: ExportRenderer(typeof(LoginView), typeof(LoginViewRenderer))]
namespace ShowsCalendar.Droid.ViewRenderer
{
public class LoginViewRenderer : PageRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);

        var context = Forms.Context;

        var baseAddress = ConfigHelper.TraktAPIURL;
        var auth = new OAuth2Authenticator(
            clientId: ConfigHelper.ClientID,
            redirectUrl: new Uri("urn:ietf:wg:oauth:2.0:oob"),
            scope: "",
            authorizeUrl: new Uri(baseAddress + "/oauth/authorize?response_type=code")
            );
        auth.AllowCancel = true;
        auth.Completed += AuthenticateCompleted;            
        var intent = auth.GetUI(context);
        context.StartActivity(intent);
    }

    private void AuthenticateCompleted(object sender, AuthenticatorCompletedEventArgs e)
    {
        if (!e.IsAuthenticated)
        {
            return;                
        }
        App.AccessToken = e.Account.Properties["access_token"].ToString();
        AccountStore.Create().Save(e.Account, "Trakt");
    }
}

}


Source: (StackOverflow)