Xamarin的OAuth1Authenticator.Auth没有终止未完成

时间:2017-10-13 14:27:21

标签: android authentication xamarin oauth xamarin.auth

我目前正在尝试在REST应用内使用xamarin.forms服务。

要执行身份验证,请使用以下代码:

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);

现在,在进行身份验证后,用户将被重定向到customprot://oauth1redirect。为了捕获这个重定向,我添加了一个新的IntentFilter(对于Android),如下所示:

 [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();
    }
}

据我了解xamarin.auth的文档,这将触发OAuth1Authenticator解析生成的网址以获取经过身份验证的用户凭据,并最终触发CompletedError事件。但令人惊讶的是没有任何事情发生:没有调用事件或引发错误。由于这使调试更难,我真的不知道如何解决这个问题。因此,我也在寻找有关问题原因和可能解决方案的建议。

编辑:只是为了更清楚:调用intent的OnCreate方法,但执行OnPageLoading方法不会引发CompletedError事件验证者。

Edit2:这是我的回调代码(我在每个回调中创建了一个断点,调试器不会破坏它们或引发异常,所以我很确定,回调函数根本没有被调用)

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();
}

2 个答案:

答案 0 :(得分:1)

这可能只会帮助那些在这个问题上迷迷糊糊但可能无法回答您的特定问题的未来的人们(例如我)。使用OAuth2Authenticator时遇到相同的症状。我正在捕获重定向,并调用OnPageLoading(),但是然后我的完成事件或错误事件都没有触发。

对我来说,关键是它仅在我第二次致电身份验证器时才发生。

深入研究Xamarin.Auth源代码后,我意识到,当身份验证器调用OnSucceeded()时,如果HasCompleted为true,则它仅返回而不会引发任何事件:

来自Authenticator.cs

public void OnSucceeded(Account account)
{
    string msg = null;

    #if DEBUG
    string d = string.Join("  ;  ", account.Properties.Select(x => x.Key + "=" + x.Value));
    msg = String.Format("Authenticator.OnSucceded {0}", d);
    System.Diagnostics.Debug.WriteLine(msg);
    #endif

    if (HasCompleted)
    {
        return;
    }

    HasCompleted = true;

etc...

所以,我的问题是我一直在使用身份验证器实例。由于HasCompleted是私有集属性,因此我不得不创建一个新的Authenticator实例,现在它可以按预期工作。

也许我应该发布一个新问题并回答它。我相信社区会让我知道。

答案 1 :(得分:0)

我也遇到过这个问题,但在设法让这部分工作之后

我创建我的OAuth2Authenticatoras如下:

App.OAuth2Authenticator = new OAuth2Authenticator(
                        clientId: OAuthConstants.CLIENT_ID,
                        clientSecret: null,
                        scope: OAuthConstants.SCOPE,
                        authorizeUrl: new Uri(OAuthConstants.AUTHORIZE_URL),
                        accessTokenUrl: new Uri(OAuthConstants.ACCESS_TOKEN_URL),
                        redirectUrl: new Uri(OAuthConstants.REDIRECT_URL), //"com.something.myapp:/oauth2redirect" -- note I only have one /
                        getUsernameAsync: null,
                        isUsingNativeUI: true);

然后在我的拦截器活动中:

[Activity(Label = "GoogleAuthInterceptor")]
[IntentFilter
(
    actions: new[] { Intent.ActionView },
    Categories = new[]
    {
            Intent.CategoryDefault,
            Intent.CategoryBrowsable
    },
    DataSchemes = new[]
    {
        // First part of the redirect url (Package name)
        "com.something.myapp"
    },
    DataPaths = new[]
    {
        // Second part of the redirect url (Path)
        "/oauth2redirect"
    }
)]
public class GoogleAuthInterceptor: Activity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Create your application here
        Android.Net.Uri uri_android = Intent.Data;

        // Convert Android Url to C#/netxf/BCL System.Uri
        Uri uri_netfx = new Uri(uri_android.ToString());

        // Send the URI to the Authenticator for continuation
        App.OAuth2Authenticator?.OnPageLoading(uri_netfx);
       // remove your OnPageLoaded it results in an invalid_grant exception for me

        Finish();
    }
}

您可以尝试将DataPathPrefix =“/ oauth1redirect”)更改为

DataPaths = new[]
        {
            // Second part of the redirect url (Path)
            "/oauth1redirect"
        }

这会成功触发OAuth2Authenticator上的已完成事件,然后在演示者上触发

private async void OAuth2Authenticator_Completed(object sender, AuthenticatorCompletedEventArgs e)
{
    try
    {
        // UI presented, so it's up to us to dimiss it on Android
        // dismiss Activity with WebView or CustomTabs      
            if(e.IsAuthenticated)
        {
            App.Account = e.Account;
                var oAuthUser = await GetUserDetails();             
                // Add account to store
            AccountStore.Create().Save(App.Account, App.APP_NAME_KEY);

        }
        else
        {
            // The user is not authenticated
            // Show Alert user not found... or do new signup?
            await App.Notify("Invalid user.  Please try again");
        }
        }
    catch(Exception ex)
    {
        throw;
    }
}

在此阶段,我被重定向到应用程序。

我目前正在尝试解决未关闭演示者的问题。即使应用程序位于前台并且用户已经过身份验证,它也会在后台运行。但这应该有助于您解决问题。