Git Product home page Git Product logo

simpleauth's Introduction

Simple Auth

Every API needs authentication, yet no developer wants to deal with authentication. Simple Auth embeds authentication into the API so you dont need to deal with it. Most importantly it works great with traditional Xamarin and Xamarin.Forms

Join the chat at https://gitter.im/simpleauth/community

Android: Android Build status

iOS/MacOS: Build status

General information

Available on Nuget

Clancey.SimpleAuth

Providers

Current Built in Providers

  • Azure Active Directory
  • Amazon
  • Dropbox
  • Facebook
  • Github
  • Google
  • Instagram
  • Linked In
  • Microsoft Live Connect
  • Twitter

Simple auth ships with some built in providers so you just need to add your keys and scopes.

var scopes = new[]
{
	"https://www.googleapis.com/auth/userinfo.email",
	"https://www.googleapis.com/auth/userinfo.profile"
};
var api = new GoogleApi("google",
	   "clientid",
	   "clientsecret")
{
	Scopes = scopes,
};

var account = await api.Authenticate();

Restful Api Requests

Restful Api Requests couldnt be simpler

var song = await api.Get<Song>("http://myapi/Song/",songId);

Paramaters can be added as part of the path

var todoItem = await api.Get<TodoItem>("http://myapi/user/{UserId}/TodoItem",new Dictionary<string,string>{["UserId"] = "1", ["itemID"] = "22"});

Generates the following Url:

http://myapi/user/1/TodoItem?itemID=22

Attribute your Api Requests (Optional)

[Path("/pet")]
[ContentType("application/json")]
[Accepts("application/json")]
public virtual Task AddPet(Pet body) {
    return Post( body);
}

iOS/Mac Specific

OnePassword Support (iOS)

One password support is for iOS Only.
Simply add the project or the Nuget

Clancey.SimpleAuth.OnePassword

Then call the following line in your iOS project prior to calling api.Authenticate();

SimpleAuth.OnePassword.Activate();

Native Twitter Support via Twitter App

You can use the Twitter app to authenticate with SimpleAuth on iOS.

Add the following to your Info.Plist

// Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>twitterkit-<consumerKey></string>
    </array>
  </dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>twitter</string>
    <string>twitterauth</string>
</array>

Then call the following line in your iOS AppDelegate FinishedLaunching method;

SimpleAuth.Providers.Twitter.Init();

Also add the following override in your AppDelegate

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

Native Facebook Support via iOS SDK

Simply add the project or the Nuget

Clancey.SimpleAuth.Facebook.iOS

The Facebook SDK requires you modify your info.plist : https://components.xamarin.com/gettingstarted/facebookios

Then call the following line in your iOS AppDelegate FinishedLaunching method;

SimpleAuth.Providers.Facebook.Init(app, options);

Also add the following override in your AppDelegate

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

Native Google Support via iOS SDK

Clancey.SimpleAuth.Google.iOS

The Google SDK can do Cross-Client Login. This allows you to get tokens for the server, with one login.

To use Cross-client you need to set the ServerClientId on the GoogleApi.

Call the following in your FinishedLaunching Method;

SimpleAuth.Providers.Google.Init()

Also add the following to your AppDelegate

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

If you need Cross-client authentication

var api = new GoogleApi("google","client_id"){
	ServerClientId = "server_client_id""
};
var account = await api.Authenticate ();
var serverToken = account.UserData ["ServerToken"];

Troubleshooting

System.Exception: Error Domain=com.google.GIDSignIn Code=-2 "keychain error" UserInfo={NSLocalizedDescription=keychain error}

Under the iOS Build Signing, Custom Entitlements: make sure an entitlement.plist is set

Native SFSafariViewController iOS/MacOS

SFSafariViewController Allows users to use Safari to login, instead of embedded webviews.

Google now requires this mode and is enabled by default for Google Authentication on iOS/MacOS.

To use the Native Safari Authenticator, you are required to add the following snippet in your AppDelegate (iOS Only)

public override bool OpenUrl (UIApplication app, NSUrl url, NSDictionary options)
{
	if (SimpleAuth.Native.OpenUrl(app, url, options))
		return true;
	return base.OpenUrl(app,url,options);
}

You are also required to add the following to add a CFBundleURLSchemes to your info.plist

For Google: com.googleusercontent.apps.YOUR_CLIENT_ID

	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>com.googleusercontent.apps.YOURCLIENTID</string>
			</array>
			<key>CFBundleURLName</key>
			<string>googleLogin</string>
		</dict>
	</array>
	

Android

Google Sign-In on Android

Simple Auth supports the native Google Sign-in for Android.

  1. Add the nuget Clancey.SimpleAuth.Google.Droid

  2. Create OAuth Client Id (Web Application): Link

  3. Create and OAuth Android app: Link

    • Sign your app using the same Keystore
  4. Use both the Web Application ClientID. ClientSecret is not required but reccomended.

  5. Add the following code to your Main Activity

    protected override void OnCreate(Bundle bundle)
    {
    	base.OnCreate(bundle);
    	SimpleAuth.Providers.Google.Init(this.Application);
    	//The rest of your initialize code
    }
    
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
       base.OnActivityResult(requestCode, resultCode, data);
    	SimpleAuth.Native.OnActivityResult (requestCode,resultCode,data); 
    }

If you need Cross-Client authentication pass your ServerClientId into the google api

var api = new GoogleApi("google","client_id"){
	ServerClientId = "server_client_id""
};
var account = await api.Authenticate ();
var serverToken = account.UserData ["ServerToken"];

Troubleshooting

If you get: Unable to find explicit activity class {com.google.android.gms.auth.api.signin.internal.SignInHubActivity}; have you declared this activity in your AndroidManifest.xml?

Add the following to your AndroidManifest.xml

<activity android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity"
		android:screenOrientation="portrait"
		android:windowSoftInputMode="stateAlwaysHidden|adjustPan" />
	</application>

Status Code 12501 (unknown) Your app signing or tokens are invalid

  1. Check your app is signed with the same KeyStore noted in for your android app Link
  2. Regenerate new OAuth 2 Client id, create the WebApplication kind.

Native Facebook for Android

Simple Auth supports the native Facebook SDK for Android.

  1. Add the nuget Clancey.SimpleAuth.Facebook.Droid

  2. Create an Android App: Link

  3. Add the following to your String.xml in Resources/values. If your appId was 1066763793431980

    <string name="facebook_app_id">1066763793431980</string>
    <string name="fb_login_protocol_scheme">fb1066763793431980</string>
    
  4. Add a meta-data element to the application element:

    [assembly: MetaData("com.facebook.sdk.ApplicationId", Value = "@string/facebook_app_id")]
    
  5. Add FacebookActivity to your AndroidManifest.xml:

    <activity android:name="com.facebook.FacebookActivity"
          android:configChanges=
                 "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
          android:label="@string/app_name" />          
    <activity
        android:name="com.facebook.CustomTabActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="@string/fb_login_protocol_scheme" />
        </intent-filter>
    </activity>
    
  6. Add the following code to your Main Activity

    protected override void OnCreate(Bundle bundle)
    {
    	base.OnCreate(bundle);
    	SimpleAuth.Providers.Google.Init(this.Application);
    	//The rest of your initialize code
    }
    
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
       base.OnActivityResult(requestCode, resultCode, data);
    	Native.OnActivityResult (requestCode,resultCode,data); 
    }

CustomTabs for Android

SimpleAuth supports using Custom Tabs for authorization.

  1. Add the nuget Clancey.SimpleAuth.Droid.CustomTabs

  2. In your Droid project, create a subclass of SimpleAuthCallbackActivity to handle your url scheme, replacing the value of DataScheme with the scheme you used for the redirectUrl parameter of the Api constructor

    [Activity(NoHistory = true, LaunchMode = Android.Content.PM.LaunchMode.SingleTop)]
    [IntentFilter(new [] { Intent.ActionView},
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable},
        DataScheme = "YOUR CUSTOM SCHEME")]
    public class MyCallbackActivity : SimpleAuthCallbackActivity
    {
    }

.Net Core

You will need to implement an AuthStorage

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Linq;

namespace SimpleAuth
{
	public class AuthStorage : IAuthStorage
	{
		private const int Keysize = 128;
		private const int DerivationIterations = 1000;

		public static string EncryptString(string plainText, string passPhrase)
		{
			var saltStringBytes = Generate256BitsOfRandomEntropy();
			var ivStringBytes = Generate256BitsOfRandomEntropy();
			var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
			using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
			{
				var keyBytes = password.GetBytes(Keysize / 8);
				using (var symmetricKey = new RijndaelManaged())
				{
					symmetricKey.BlockSize = Keysize;
					symmetricKey.Mode = CipherMode.CBC;
					symmetricKey.Padding = PaddingMode.PKCS7;
					using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
					{
						using (var memoryStream = new MemoryStream())
						{
							using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
							{
								cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
								cryptoStream.FlushFinalBlock();
								// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
								var cipherTextBytes = saltStringBytes;
								cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
								cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
								memoryStream.Close();
								cryptoStream.Close();
								return Convert.ToBase64String(cipherTextBytes);
							}
						}
					}
				}
			}
		}

		public static string DecryptString(string cipherText, string passPhrase)
		{
			var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
			var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
			var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
			var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

			using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
			{
				var keyBytes = password.GetBytes(Keysize / 8);
				using (var symmetricKey = new RijndaelManaged())
				{
					symmetricKey.BlockSize = Keysize;
					symmetricKey.Mode = CipherMode.CBC;
					symmetricKey.Padding = PaddingMode.PKCS7;
					using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
					{
						using (var memoryStream = new MemoryStream(cipherTextBytes))
						{
							using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
							{
								var plainTextBytes = new byte[cipherTextBytes.Length];
								var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
								memoryStream.Close();
								cryptoStream.Close();
								return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
							}
						}
					}
				}
			}
		}

		private static byte[] Generate256BitsOfRandomEntropy()
		{
			var randomBytes = new byte[16];
			using (var rngCsp = new RNGCryptoServiceProvider())
			{
				rngCsp.GetBytes(randomBytes);
			}
			return randomBytes;
		}

		static string CalculateMD5Hash(string input)
		{
			var md5 = MD5.Create();

			var inputBytes = Encoding.ASCII.GetBytes(input);
			var hash = md5.ComputeHash(inputBytes);
			var sb = new StringBuilder();

			for (int i = 0; i < hash.Length; i++)
			{
				sb.Append(hash[i].ToString("X2"));
			}

			return sb.ToString();

		}

		public void SetSecured(string identifier, string value, string clientId, string clientSecret, string sharedGroup)
		{
			var key = $"{clientId}-{identifier}-{clientId}-{sharedGroup}";
			var newKey = CalculateMD5Hash(key);
			var encrypted = EncryptString(value, clientSecret);
			Plugin.Settings.CrossSettings.Current.AddOrUpdateValue(newKey, encrypted);
		}

		public string GetSecured(string identifier, string clientId, string clientSecret, string sharedGroup)
		{
			try
			{
				var key = $"{clientId}-{identifier}-{clientId}-{sharedGroup}";
				var newKey = CalculateMD5Hash(key);
				var cryptText = Plugin.Settings.CrossSettings.Current.GetValueOrDefault(newKey, "");
				return DecryptString(cryptText, clientSecret);
			}
			catch (Exception ex)
			{
				//Console.WriteLine(ex);
			}
			return null;
		}
	}
}

For console apps, you will also need to implement the Authenticators:

Basic Auth

using System;
using System.Security;
using System.Threading.Tasks;
namespace SimpleAuth
{
    public class BasicAuthController
    {
        readonly IBasicAuthenicator authenticator;

        public BasicAuthController(IBasicAuthenicator authenticator)
        {
            this.authenticator = authenticator;
        }


        public async Task<Tuple<string, string>> GetCredentials(string title, string details = "")
        {
            try
            {
                Console.WriteLine("******************");
                Console.WriteLine(title);
                Console.WriteLine(details);
                Console.WriteLine("******************");
                Console.WriteLine("Enter Username:");
                var username = Console.ReadLine();
                Console.WriteLine("Enter Password:");
                var password = GetPassword();

                var result = new Tuple<string, string>(username, password);
                try
                {
                    bool success = false;
                    var basic = authenticator;
                    if (basic != null)
                    {
                        success = await basic.VerifyCredentials(result.Item1, result.Item2);
                    }
                    if (!success)
                        throw new Exception("Invalid Credentials");
                }
                catch (Exception ex)
                {
                    result = await GetCredentials(title, $"Error: {ex.Message}");
                }
                return result;
            }
            catch (TaskCanceledException)
            {
                authenticator.OnCancelled();
                return null;
            }
        }
        public string GetPassword()
        {
            var pwd = "";
            while (true)
            {
                ConsoleKeyInfo i = Console.ReadKey(true);
                if (i.Key == ConsoleKey.Enter)
                {
                    break;
                }
                else if (i.Key == ConsoleKey.Backspace)
                {
                    if (pwd.Length > 0)
                    {
                        pwd.Remove(pwd.Length - 1);
                        Console.Write("\b \b");
                    }
                }
                else
                {
                    pwd += (i.KeyChar);
                    Console.Write("*");
                }
            }
            return pwd;
        }
    }
}

Web Authenticator

using System;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SimpleAuth
{
    public class WebAuthenticatorController
    {
        readonly WebAuthenticator authenticator;

        public WebAuthenticatorController(WebAuthenticator authenticator)
        {
            this.authenticator = authenticator;
        }


        public async Task GetCredentials(string title, string details = "")
        {
            try
            {
                var url = await authenticator.GetInitialUrl();
                Console.WriteLine("******************");
                Console.WriteLine(title);
                Console.WriteLine(details);
                Console.WriteLine($"Launching Url: \"{url}\"");
                Console.WriteLine("******************");
                Console.WriteLine("Paste the Redirected URL Here:");
                OpenBrowser(url);
                var username = Console.ReadLine();

                try
                {
                    bool success = false;
                    var basic = authenticator;
                    if (basic != null)
                    {
                        success = basic.CheckUrl(new Uri(username), null);
                    }
                    if (!success)
                        throw new Exception("Invalid Credentials");
                }
                catch (Exception ex)
                {
                    await GetCredentials(title, $"Error: {ex.Message}");
                }
            }
            catch (TaskCanceledException)
            {
                authenticator.OnCancelled();
            }
        }

        public static void OpenBrowser(Uri uri)
        {
            OpenBrowser(uri.AbsoluteUri);
        }

        public static void OpenBrowser(string url)
        {
            try
            {
                Process.Start(url);
            }
            catch
            {
                // hack because of this: https://github.com/dotnet/corefx/issues/10361
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    url = url.Replace("&", "^&");
                    Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    Process.Start("xdg-open", url);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    Process.Start("open", url);
                }
                else
                {
                    throw;
                }
            }
        }
    }
}

simpleauth's People

Contributors

allan-chin avatar antonioseric avatar clancey avatar dependabot[bot] avatar jamesatgithub avatar jasallen avatar jonlipsky avatar kentcb avatar kowalskip avatar matthidinger avatar micdoug avatar redth avatar rhedgpeth avatar robgibbens avatar rpierry avatar shkurtia avatar snavatta avatar superlloyd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simpleauth's Issues

Status{statusCode=DEVELOPER_ERROR, resolution=null}

Hello developers , please i face this problem and i searched over the day for a solution but no way
System.Exception: Status{statusCode=DEVELOPER_ERROR, resolution=null} this error show after choosing google account , i searched and found that the sha1 and package name missmatching but all configuration are right
result code is canceled (41221) aany help please !

OAuthAccount should return id_token for client that needs to pass it to backend server

Usefulness of this is discussed here: https://developers.google.com/identity/sign-in/ios/backend-auth

...you might need to identify the currently signed-in user on the server.

The code is already receiving id_token from the server (if, for Google OAuth2, email or profile scope is specified), but it just needs to be saved into the OAuthAccount object.

I'm able to do this with the following subclasses, but it would be much simpler to modify the GoogleApi class.

    public class OAuthAccountWithIdToken : OAuthAccount
    {
        public string IdToken;
    }

    public class GoogleApiWithIdToken : GoogleApi
    {
        public GoogleApiWithIdToken (string identifier, string clientId, string clientSecret, HttpMessageHandler handler = null) : base(identifier, clientId, clientSecret, handler)
        {
        }

        protected override async Task<OAuthAccount> GetAccountFromAuthCode (WebAuthenticator authenticator, string identifier)
        {
            var postData = await authenticator.GetTokenPostData (ClientSecret);
            if (string.IsNullOrWhiteSpace (TokenUrl))
                throw new Exception ("Invalid TokenURL");
            var message = new HttpRequestMessage (HttpMethod.Post, TokenUrl) {
                Content = new FormUrlEncodedContent (postData),
                Headers = {
                    {"Accept","application/json"}
                }
            };
            var reply = await Client.SendAsync (message);
            var resp = await reply.Content.ReadAsStringAsync ();
            var result = Deserialize<OauthResponse> (resp);
            if (!string.IsNullOrEmpty (result?.Error))
                throw new Exception (result.ErrorDescription);

            var account = new OAuthAccountWithIdToken () {
                ExpiresIn = result.ExpiresIn,
                Created = DateTime.UtcNow,
                RefreshToken = result.RefreshToken,
                Scope = authenticator.Scope?.ToArray (),
                TokenType = result.TokenType,
                Token = result.AccessToken,
                ClientId = ClientId,
                Identifier = identifier,
                Cookies = authenticator.Cookies,
                IdToken = result.Id // id_token
            };
            return account;
        }
    }

Sample has invalid and unneeded client secret

In samples/Sample.Droid/MainActivity.cs, the string "native" is provided in the client secret field to the GoogleApi constructor.

This results in an "invalid_client" error on iOS. The value that works is null. A secret is not applicable to a native application.

Facebook on Droid failing with NoSuchMethodError: No virtual method launchUrl

It appears that the Facebook login fails to lunch properly (tried it with both the secret and using "native".

var apiFb = new FacebookApi("facebook", authProviderInfo.ClientId, "native");
var authenticate = await apiFb.Authenticate();

Error:

java.lang.NoSuchMethodError: No virtual method launchUrl(Landroid/app/Activity;Landroid/net/Uri;)V in class Landroid/support/customtabs/CustomTabsIntent; or its super classes (declaration of 'android.support.customtabs.CustomTabsIntent' appears in /data/app/com.prepify.app-HbwELJsyQUL0tzsHVqmPfw==/base.apk)

10-18 00:37:34.545 E/AndroidRuntime(18944): java.lang.NoSuchMethodError: No virtual method launchUrl(Landroid/app/Activity;Landroid/net/Uri;)V in class Landroid/support/customtabs/CustomTabsIntent; or its super classes (declaration of 'android.support.customtabs.CustomTabsIntent' appears in /data/app/com.prepify.app-HbwELJsyQUL0tzsHVqmPfw==/base.apk)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at com.facebook.internal.CustomTab.openCustomTab(CustomTab.java:50)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at com.facebook.CustomTabMainActivity.onCreate(CustomTabMainActivity.java:67)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.Activity.performCreate(Activity.java:6975)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.ActivityThread.-wrap11(Unknown Source:0)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.os.Handler.dispatchMessage(Handler.java:105)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.os.Looper.loop(Looper.java:164)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at android.app.ActivityThread.main(ActivityThread.java:6541)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at java.lang.reflect.Method.invoke(Native Method)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
10-18 00:37:34.545 E/AndroidRuntime(18944): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

I spent a considerable amount of time trying to find out where the issue lie. Comparing to your sample application, I have all the needed libraries and versions. Is there anything else you could suggest could be done?

Invalid URI: The URI is empty.

I am trying to use GoogleApi native API to authenticate users on Android. At first I was able to login just fine and everything worked perfectly, until I invoked GoogleApi.Logout for the first time. Now every time I want to authenticate, it throws an System.UriFormatException exception. Even restarting the app doesn't fix it.

I downloaded the code and I found out that the exception is caused by this line in Google.cs:

authenticator.RedirectUrl = new Uri(authenticator.GetRedirectUrl());

And this is the GetRedirectUrl function:

public virtual string GetRedirectUrl ()
{
#if __UNIFIED__
    //for google, the redirect is a reverse of the client ID
    return $"com.googleusercontent.apps.{ClientId}:/oauthredirect";
#elif WINDOWS_UWP
    return "urn:ietf:wg:oauth:2.0:oob";
#else
    if (IsUsingNative)
        return "";
#endif
    return RedirectUrl.OriginalString;
}

The error is caused by return "", the constructor for Uri doesn't accept empty strings. I went ahead and replaced it by a dummy url ("https://google.com") and it solved the problem.

Versions:

  • Android API Version: 8.0
  • Xamarin.Forms: 2.5.0.121934
  • Clancey.SimpleAuth: 1.0.46
  • Clancey.SimpleAuth.Google.Droid: 1.0.9

Stack Trace:

  at System.Uri.CreateThis (System.String uri, System.Boolean dontEscape, System.UriKind uriKind) [0x0007b] in <10a067eff09446018662189377d200e9>:0 
  at System.Uri..ctor (System.String uriString) [0x00014] in <10a067eff09446018662189377d200e9>:0 
  at SimpleAuth.Providers.GoogleApi.CreateAuthenticator () [0x00066] in C:\Projects\SimpleAuth\src\SimpleAuth\Providers\Google.cs:118 
  at SimpleAuth.OAuthApi+<PerformAuthenticate>d__32.MoveNext () [0x0028c] in C:\Projects\SimpleAuth\src\SimpleAuth\OAuth\OAuthApi.cs:155 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at SimpleAuth.AuthenticatedApi+<Authenticate>d__15.MoveNext () [0x000ad] in C:\Projects\SimpleAuth\src\SimpleAuth\Api\AuthenticatedApi.cs:65 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at App14.MainPage+<Google_Clicked>d__1.MoveNext () [0x000ad] in C:\Users\Muham\Source\Repos\App14\App14\App14\MainPage.xaml.cs:37 

iOS Google native, invalid argument when ServerClientId is null

There is a problem when using google native implementation on iOS when we don't need to use ServerClientId. The Google.cs calls the method GoogleAuthenticator.GetGoogleClientId(authenticator.ServerClientId); that throws an exception when ServerClientId is null. This problem can be solved by checking authenticator.ServerClientId before calling that method.

iOS Facebook Native null reference at login callback

Hi. I have found an error with the callback code that is triggered when the user successfully logged in facebook. In the project SimpleAuth.Facebook.iOS at line 17 we have this code:

Native.RegisterCallBack ("facebook",(UIApplication appplication, NSUrl url, NSDictionary options) => OpenUrl(appplication,url, options as NSDictionary<NSString, NSObject>));

options as NSDictionary<NSString, NSObject> returns a null reference, it seems that the cast fails. I have tried a simple modification, replacing the lambda expression with the method:

private static bool Callback(UIApplication application, NSUrl url, NSDictionary options)
{
      NSDictionary<NSString, NSObject> converted = new NSDictionary<NSString, NSObject>(
             options.Keys.Select(x => x as NSString).ToArray(),
             options.Values);
                                   
      return OpenUrl(application, url, converted);
}

This works perferctly for me. I'm have a similar problem with null references in SimpleAuth.Google.iOS too, but I'm investigating it yet. I don't know if this is the best way to solve, but it works for me.

Native Google Login iOS exception

Hi.

I'm trying to use the library to login via Google Native Client in iOS, but I'm facing the exception "Value cannot be null.\nParameter name: value" when calling authenticate.
I called SimpleAuth.Providers.Google.Init(); in the AppDelegate as is required. In the android project it works fine, so I think it is not a problem with credentials.
Do you have any idea of what is the problem?

Thanks in advance.

Facebook Authentication

Hi,

I'm trying to add Facebook Authentication to my Xamarin project.

    public async Task<bool> LoginWithFacebookAsync()
    {
        var api = new FacebookApi("facebook", "", "");
        try
        {
            var account = await api.Authenticate();
        }
        catch (TaskCanceledException)
        {
            Console.WriteLine("Canceled");
            // todo
            //MainPage.DisplayAlert("Error", "User Canceled", "Ok");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            // todo
            //MainPage.DisplayAlert("Error", ex.Message, "Ok");
        }
        return true;
    }

An error is displayed in the facebook window "The parameter app_id is required". I've tried on UWP and Android. The sample project in SimpleAuth also gives the same message when using the facebook button.

What am I doing wrong?

A task was cancelled

I have a problem with login with google. Exception throws when i am trying to login
Exception: "A task was cancelled" after i try call

var account = await AuthAsync(google);

I have tried to check example. But It throws the same exception.

Google Login Bug

When I use google login in my Android app, while this code executes :
var user = await api.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json");
My screen flashes 3 times and OnAppearing method gets called 3 times.
After that I'm signed in normally.
Is this normal behaviour ?
Thanks in advance.

Google Auth by WebView will not be allowed

Hi As per this link Google Auth by webview will be rolled out, any plan to provide new auth for Google?

https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html

"The rollout schedule for the deprecation of web-views for OAuth requests to Google is as follows. Starting October 20, 2016, we will prevent new OAuth clients from using web-views on platforms with a viable alternative, and will phase in user-facing notices for existing OAuth clients. On April 20, 2017, we will start blocking OAuth requests using web-views for all OAuth clients on platforms where viable alternatives exist."

Microsoft login with UWP, login window re-opens

After successful login to Microsoft, the login-windows closes, the token is returned in account, but then the login-window re-opens and must be closes again with cancel.

Testing with Sample.Forms.UWP,:

CreateApiButton ( new MicrosoftLiveConnectApi ( "onedrive", "6243___246", "cmP____7+~}")
{
Scopes = new[] { "onedrive.readwrite", "wl.signin" },
}),

OnAccountUpdated called unnecessarily

I have a custom Account object which I parse in GetAccountFromAuthCode. On it I have a CachedUser property so I can parse my User object once per (re-)authentication, rather than every time Authenticate is called. However, I also need to clear the cached User whenever the account is updated, so I do this in OnAccountUpdated.

The problem is, this line is executed regardless of whether authentication is actually performed. The CurrentAccount setter calls OnAccountUpdated, so my CachedUser property is cleared every time Authenticate is called, regardless of whether authentication takes place.

Nuget for Xamarin.Mac

I would find it very helpful to be able to install SimpleAuth for Xamarin.Mac via a nuget package.

Implicit flow support?

Hi,

We're trying to use SimpleAuth against a back-end set up with implicit flow. We're able to successfully receive the auth token, but then this line sends a request that the server refuses to serve ("invalid request" message). However, our theory is that this request shouldn't even be sent with the implicit flow.

Does SimpleAuth support an implicit flow?

Thanks

Java.Security.UnrecoverableKeyException: no match

Hi, I'm using your library for authentication with different social media. In the case of Facebook, I'll do it with a webview. When I use the FacebookApi and show the webview. The following error appears:

screenshot_20171110-173122

The error that appears in the console is the following:

Java.Security.UnrecoverableKeyException: no match
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <896ad1d315ca4ba7b117efb8dacaedcf>:0 
  at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <7cfbebb561c54efc9010b018c0846c7e>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001f] in <7cfbebb561c54efc9010b018c0846c7e>:0 
  at Java.Security.KeyStore.GetEntry (System.String alias, Java.Security.KeyStore+IProtectionParameter protParam) [0x00050] in <9ef29c909d7e4606a46b131129da3975>:0 
  at SimpleAuth.AuthStorage.GetSecured (System.String id, System.String clientId, System.String service, System.String sharedGroup) [0x00048] in C:\Projects\SimpleAuth\src\SimpleAuth.Droid\AuthStorage.cs:33 
  at SimpleAuth.AuthenticatedApi.GetAccount[T] (System.String identifier) [0x00002] in C:\Projects\SimpleAuth\src\SimpleAuth\Api\AuthenticatedApi.cs:88 
  --- End of managed Java.Security.UnrecoverableKeyException stack trace ---
java.security.UnrecoverableKeyException: no match
	at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$StoreEntry.getObject(BcKeyStoreSpi.java:315)
	at com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi.engineGetKey(BcKeyStoreSpi.java:610)
	at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:474)
	at java.security.KeyStore.getEntry(KeyStore.java:1560)
	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.InnerGestureListener.n_onSingleTapUp(Native Method)
	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.InnerGestureListener.onSingleTapUp(InnerGestureListener.java:79)
	at android.view.GestureDetector.onTouchEvent(GestureDetector.java:640)
	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method)
	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:54)
	at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2961)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2650)
	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method)
	at md5b60ffeb829f638581ab2bb9b1a7f4f3f.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:54)

How can I solve this error?

Xamarin.Forms iOS login with different user.

I've implemented Facebook login to XF project.
Login works good. I do logout:

 SocialAuthApi = new FacebookApi("facebook", AppConstants.FacebookClientId, AppConstants.FacebookClientSecret);
 SocialAuthApi.ResetData();
 SocialAuthApi.Logout();

And after that I want to login by another user, but I can't do bcouz previous user was saved and facebook propose me log in with the same user.
How I can log in by different user?

Bolts version

The nuspec file for Droid Facebook specifies a version >= 1.4.1 yet this package and the project references are 1.4.0.1

install from nuget fails

Google login refresh token missing

I got error for not getting refresh token from google when login with google second time you install app or clear data.

I fix it by adding &prompt=consent in class SimpleAuth.Providers.GoogleAuthenticator method GetInitialUrl return new Uri(uri.AbsoluteUri + "&access_type=offline&prompt=consent");

Reference

Do you have another way to fix it?

Android Google Native check user cancelled

When the user opens the login screen and goes back, the native Google implementation always returns the status 12501. We need to check the OnActivityResult result code. I got it working using modifying the Google.cs OnActivityResult with the following code:

if (requestCode == GoogleSignInProvider.SIGN_IN_REQUEST_CODE)
            {
                if (result == Result.Canceled)
                {
                    googleSignInProvider?.FoundResult(new GoogleSignInResult(null, new Statuses(CommonStatusCodes.Canceled)));
     }
     else
     {
          var googleSignInResult = Auth.GoogleSignInApi.GetSignInResultFromIntent(data);
          googleSignInProvider?.FoundResult(googleSignInResult);
     }
     return true;
}

Google API Login: Task cancelled on Android

When I try to login into google api using this library I get a "Task cancelled exception" on android.
In iOS works fine.

I've installed SimpleAuth, SimpleAuth.Google.Droid, SimpleAuth.Droid.CustomTabs.

The error occurs selecting the google account to log in.

Any idea what I'm doing wrong?

Thanks

var api = new GoogleApi("google", "my_clientId", "") { Scopes = new[] { "https://www.googleapis.com/auth/calendar", } }; var account = await api.Authenticate(); System.Diagnostics.Debug.WriteLine(account.Identifier);

NullReferenceException. TwitterApi on UWP

Hi
Thanks for your great library =)
I am trying to use twitter for authorization in my app on desktop UWP (Xamarin Forms, NetStandart).
My code:
var api = new TwitterApi("twitter", TwitterId, TwitterSecret) { RedirectUrl = new Uri("http://mobile.twitter.com") }; var account = await api.Authenticate();
When i input correct email and password, view is providing the dialog to skip or save my credentials. Сhoosing one of this options leads to the only one result - NullReferenceException. This code works fine under macOS.

Stacktrace:
at System.Collections.Specialized.NameValueCollection.get_Item(String key)
at SimpleAuth.Providers.TwitterApi.d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at SimpleAuth.Api.<SendMessage>d__82.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at SimpleAuth.Api.d__78.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at SimpleAuth.Providers.TwitterApi.<GetAccountFromAuthCode>d__14.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at SimpleAuth.OAuthApi.d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at SimpleAuth.AuthenticatedApi.<Authenticate>d__15.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at AudioMiner.BLL.Services.Auth.AuthService.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at AudioMiner.ViewModels.Sign.SignViewModel.d__19.MoveNext()

Logging out SFSafariViewController

I have auth against a custom back-end working with SFSafariViewController, but I can't find any means via which I sign the user out. Calling ResetData against my OAuthApi and then calling Authenticate simply opens the browser, finds the existing cookie, and immediately logs the user back in.

I understand I need to send the user to the logout endpoint for my OAuth backend. But it looks like there is no support for this in SimpleAuth. Can you please confirm?

UWP Support

It would be great to have Universal Windows Platform support.

Can’t Enter Password on Gear VR Version

Hi there,

Due to the plugin holding the player’s camera completely in place, it appears to be blocking my ability to enter any text (such as to register or enter a password). I have both the SimpleAuth plugin and the helper plugin installed.

If you could please let me know what I should do to fix this, I’d really appreciate it!

Thanks so much,
Jamie

"no method with name='getSignInIntent'"

I'm getting the following when running a Release build:

no method with name='getSignInIntent' signature='(Lcom/google/android/gms/common/api/GoogleApiClient;)Landroid/content/Intent;' in class Lcom/google/android/gms/auth/api/siginin/internal/zzc;

It runs fine on Debug, but it doesn't do so in Release.

I'm using Visual Studio 2017.

I tried without linking, without ProGuard, etc.

Thanks!

Error processing method: CheckNewGooglePlayServices

Since changing Target Framework to use Android 8.0 (Oreo), I'm getting the following error on release builds:

7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: The "LinkAssemblies" task failed unexpectedly.
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: Mono.Linker.MarkException: Error processing method: 'System.Void SimpleAuth.Providers.Google/GoogleSignInProvider::CheckNewGooglePlayServices(Android.App.Activity)' in assembly: 'SimpleAuth.Google.Droid.dll' ---> Mono.Cecil.ResolutionException: Failed to resolve System.Boolean Android.Gms.Common.Zze::IsUserResolvableError(System.Int32)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessQueue()
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: --- End of inner exception stack trace ---
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessQueue()
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.ProcessEntireQueue()
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.Process()
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Mono.Linker.Pipeline.Process(LinkContext context)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at MonoDroid.Tuner.Linker.Process(LinkerOptions options, LinkContext& context)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Xamarin.Android.Tasks.LinkAssemblies.Execute(DirectoryAssemblyResolver res)
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Xamarin.Android.Tasks.LinkAssemblies.Execute()
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
7>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1696,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.d__26.MoveNext()

I'm using the following versions:
Clancey.SimpleAuth 1.0.41
Clancey.SimpleAuth.Google.Droid 1.0.9

(Not using version 1.0.47 of Clancey.SimpleAuth because I'm still using PCL's.)

My linking is set to "Sdk Assemblies Only".

Note that I still get the error even if I include "SimpleAuth;SimpleAuth.Google.Droid" in the "Skip linking assemblies" section.

(It compiles fine if I change the "Linking" to "None", but this is obviously not ideal.)

Error description is lost when exception thrown

After authenticator.GetTokenPostData, the codes assumes that the ErrorDescription will be available, but that is not the case e.g. when the error is "invalid_client". I changed:

if (!string.IsNullOrEmpty(result?.Error))
     throw new Exception(result.ErrorDescription);

to:

if (!string.IsNullOrEmpty (result?.Error))
                throw new Exception (result.ErrorDescription ?? result.Error);

SFAuthenticationSession doesn't seem to save account

Running the authenticate method on the dropboxapi on android and on iOS 9 seems to save the account access token and other account info as calling it a second time doesn't prompt the user. But on iOS 11 with the SFAuthenticationSession it will present the safari view every time authenticate is called.

Facebook Login issues on iOS and Android

Hi,

I'm having trouble with Facebook, the errors are different on each platform.

On iOS : I get this error when connecting -> Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Publish or manage permissions are not permitted to be requested with read permissions.'
My scopes are -> "publish_actions", "manage_pages", "publish_pages"
There is no reading scope. On android i can set RequestPublishPermission to true during Init, is there the same concept on iOS or do you know how I could fix that ?

On Android :
[MonoDroid] UNHANDLED EXCEPTION: [MonoDroid] System.ArgumentOutOfRangeException: Value to add was out of range. [MonoDroid] Parameter name: value [MonoDroid] at System.DateTime.Add (System.Double value, System.Int32 scale) [0x00066] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 [MonoDroid] at System.DateTime.AddMilliseconds (System.Double value) [0x00000] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 [MonoDroid] at SimpleAuth.Providers.Facebook+<Login>d__9.MoveNext () [0x001ce] in C:\Projects\SimpleAuth\src\SimpleAuth.Facebook.Droid\Facebook.cs:80 [MonoDroid] --- End of stack trace from previous location where exception was thrown --- [MonoDroid] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 [MonoDroid] at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 [MonoDroid] at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <ff199c98c3f84852925dd37a0ef6113a>:0 [MonoDroid] at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <ff199c98c3f84852925dd37a0ef6113a>:0 [MonoDroid] at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <ff199c98c3f84852925dd37a0ef6113a>:0 [MonoDroid] at (wrapper dynamic-method) System.Object.feff4966-163e-4e01-a90b-ea3d5323e862(intptr,intptr)

The login seems to work but when it goes here \SimpleAuth.Facebook.Droid\Facebook.cs:80 it crashes. Any idea how I could fix that ?

Thanks for this plugin btw, I added Google login, not without some struggle, but now it works great !

Google login with UWP, window not closing

After successful login to Google, the login-windows stays open and the token is displayed:

"Please copy this code, switch tzo your app and paste there:
4/.AAAwhc9lp___________a2Zrb3a4_3xDWGw"

Should the window not close automatically and return the token in account?

Testing with Sample.Forms.UWP,:

CreateApiButton( new GoogleApi("google drive", "16_______5t9.apps.googleusercontent.com", "")
{
Scopes = new[] {"https://www.googleapis.com/auth/drive" },
}),

Dropbox v2

SimpleAuth.Providers.DropBoxApi.cs is still on DropBox api v1, which doesn't work anymore.
I like SimpleAuth because its lean and slim without unnecessary dependencies, but I need some help with the dropbox api v2?

Thanks, Tom

Add support for Android Target SDK API 23 (currently Google Sign In crashes)

If you target API 23+ the app must prompt the user for GetAccounts permission:

https://blog.xamarin.com/requesting-runtime-permissions-in-android-marshmallow/

We need to add a call to CheckSelfPermission.

Without that, I am finding that Authenticate() throws an exception, which I catch, but even so my app terminates with:

System.InvalidOperationException: An attempt was made to transition a task to a final state when it had already completed.
  at System.Threading.Tasks.TaskCompletionSource`1[TResult].SetResult (TResult result) [0x0000c] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/TaskCompletionSource.cs:322
  at Android.Gms.Extensions.GoogleApiClientExtensions+<BuildAndConnectAsync>c__AnonStorey0.<>m__0 (Android.OS.Bundle hint) [0x00000] in <1db671c6182d42a7b22c48ed6b33a584>:0
  at Android.Gms.Common.Apis.GoogleApiClientConnectionCallbacksImpl.OnConnected (Android.OS.Bundle bundle) [0x0000d] in <1db671c6182d42a7b22c48ed6b33a584>:0
  at Android.Gms.Common.Apis.GoogleApiClient+IConnectionCallbacksInvoker.n_OnConnected_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_connectionHint) [0x00011] in <1db671c6182d42a7b22c48ed6b33a584>:0
  at at (wrapper dynamic-method) System.Object:a6b03050-593a-4ddc-9bdf-441125fda0bf (intptr,intptr,intptr)

Android release build throwing JsonSerializationException during Google Sign In

I think this could be avoided by adding [Preserve(AllMembers = true)] to GoogleUserProfile. See https://forums.xamarin.com/discussion/15152/deserialization-not-working-with-json-net-on-ios-device-ios-simulator-works

6-08 09:32:22.452 18910 18910 I mono-stdout: Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type SimpleAuth.Providers.GoogleUserProfile. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'id', line 2, position 6.
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract objectContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id, System.Boolean& createdFromNonDefaultCreator) [0x000d5] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x00143] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) [0x0006d] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000dc] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00053] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x00000] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x0002d] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value) [0x00000] in <7039dea96b04466eab27c6e18a0e4a63>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at SimpleAuth.JSonExtensions.ToObject[T] (System.String str) [0x00030] in <65cd46195b024b08a2cbec0966fa3d5e>:0 
06-08 09:32:22.452 18910 18910 I mono-stdout:   at SimpleAuth.Api.Deserialize[T] (System.String data) [0x00000] in <65cd46195b024b08a2cbec0966fa3d5e>:0 

Google native login not working

Clancey.SimpleAuth: 1.0.49
Clancey.SimpleAuth.Google.Droid: 1.0.9

This is my code
` var api = new GoogleApi("google",
"my_client_id",
GoogleApi.NativeClientSecret) //native client secret only for Android
{
Scopes = scopes
};

        try
        {
            OAuthAccount account = await api.Authenticate() as OAuthAccount;
            if (account != null)
            {

            }
            else
            {
                await UserDialogs.Instance.AlertAsync("Login Failed!");
            }
        }
        catch (TaskCanceledException e)
        {
            await UserDialogs.Instance.AlertAsync($"canceled");
        }`

This shows the list of google accounts on my phone on ai.Authenticate() call, but after choosing any account always hits Task Canceled exception.

On my activity:
`protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);

        SimpleAuth.Native.OnActivityResult(requestCode, resultCode, data);
    }`

The requestCode is 41221 and resultData Android.App.Result.Canceled

Not sure if I am missing anything here.

FacebookApi - Null reference exception

with latest 1.0.20 the facebookapi broken:

[0:] System.NullReferenceException: Object reference not set to an instance of an object.
at SimpleAuth.Providers.FacebookApi.<.ctor>b__8_0 (SimpleAuth.WebAuthenticator a) [0x00007] in :0
at SimpleAuth.OAuthApi+d__31.MoveNext () [0x0023d] in :0

I tried to debug it with the source code but got a weird error location at line of 152 in Twitter.cs

TwitterApi - Null Reference exception

Just installed the latest 1.0.19 (for using the fix of cookie per api call), but fond my old code doesn't work on calling the Authenticate method of TwitterApi:

at SimpleAuth.OAuthApi+d__31.MoveNext () [0x00042] in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357 at SimpleAuth.AuthenticatedApi+<Authenticate>d__15.MoveNext () [0x000c1] in <filename unknown>:0 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/3412/3cf8aaed/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357

SimpleAuth for Winforms

I'm trying to add a class to use SimpleAuth also in WinForm-apps. Actually not so difficult. Just a new class-library with a Login-Form with a WebBrowser-control and a implementation of IAuthStorage.
It works fine, but I only have one small problem.

How to change user for OneDrive?

I can change user for DropBox just by deleting the stored account in IAuthStorage. Then DropBox is showing the login-window on next time.
But for OneDrive this doesn't work with my Forms.WebBrowser implementation. I'm still logged in. The url-call from authenticator.GetInitialUrl() is immediately answered with a valid code.

Maybe something with cookies? Any ideas?

Tom

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.