【问题标题】:OAuth1Authenticator of Xamarin.Auth not terminating not completingXamarin.Auth 的 OAuth1Authenticator 未终止未完成
【发布时间】:2018-03-25 17:22:47
【问题描述】:

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

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

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 解析生成的url 以获取经过身份验证的用户的凭据,并最终触发CompletedError 事件。但令人惊讶的是,什么也没发生:没有调用任何事件或引发错误。由于这使调试变得更加困难,我真的不知道如何解决这个问题。因此,我也在寻找有关问题原因和可能解决方案的建议。

编辑:为了更清楚一点:调用意图的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();
}

【问题讨论】:

  • 能否请您为authenticator.Completed 发布您的Aut_Completed 回调。我用 v1 测试了我的代码,它运行良好。首先调用authenticator.Completed,然后再调用presenter完成。
  • @don.coda 查看我的编辑。

标签: android authentication xamarin oauth xamarin.auth


【解决方案1】:

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

对我来说关键是它只发生在我第二次调用 Authenticator 时。

在挖掘 Xamarin.Auth 源代码后,我意识到如果在身份验证器调用 OnSucceeded() 时 HasCompleted 为真,它只会返回而不引发任何事件:

来自 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 是一个私有集合属性,我必须创建一个新的身份验证器实例,现在一切正常。

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

【讨论】:

    【解决方案2】:

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

    我按如下方式创建我的 OAuth2Authenticator:

    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 上的 Completed 事件,然后是演示者上的事件

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

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

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

    【讨论】:

    • 也许我没有完全清楚我的问题:调用了意图的OnCreate 方法,但是执行OnPageLoading 方法不会引发CompletedErrors 事件身份验证器。
    • 好的,我现在明白了。您是否尝试过使用 OAuth2Authenticator 身份验证器?还是您特别需要版本 1?
    • 是的。遗憾的是,该服务仅支持版本 1。
    猜你喜欢
    • 1970-01-01
    • 2019-05-18
    • 2020-02-26
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    相关资源
    最近更新 更多