3

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

编辑:只是为了让这一点更清楚: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();
}
4

2 回答 2

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 是一个私有集合属性,我必须创建一个新的身份验证器实例,现在一切都按预期工作。

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

于 2018-08-22T18:20:17.230 回答
0

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

我创建我的 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;
    }
}

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

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

于 2017-10-13T20:54:35.093 回答