C# Xamarin:从浏览器重定向到本机应用程序';行不通

C# Xamarin:从浏览器重定向到本机应用程序';行不通,c#,xamarin,oauth-2.0,identityserver4,C#,Xamarin,Oauth 2.0,Identityserver4,为了在我的xamarin应用程序中实现oauth2授权代码流,我遵循了以下文档: 此外,我参考了本教程以使其与IdentityServer4一起使用(我复制了OAuth2Authenticator类的扩展): 当我启动Loginflow时,应用程序将重定向到浏览器,我可以登录并允许访问用户数据。不幸的是,浏览器(或者我猜是操作系统)没有重定向到我的应用程序。我猜我的重定向url有问题,但我不确定。任何关于它为什么不起作用的建议都将不胜感激 重定向Uri由manifest.xml中的确切包名加

为了在我的xamarin应用程序中实现oauth2授权代码流,我遵循了以下文档:

此外,我参考了本教程以使其与IdentityServer4一起使用(我复制了OAuth2Authenticator类的扩展):

当我启动Loginflow时,应用程序将重定向到浏览器,我可以登录并允许访问用户数据。不幸的是,浏览器(或者我猜是操作系统)没有重定向到我的应用程序。我猜我的重定向url有问题,但我不确定。任何关于它为什么不起作用的建议都将不胜感激

重定向Uri由manifest.xml中的确切包名加上“:/oauth2redirect”组成。虽然可能很明显,但我想说的是,我用ipadress替换了身份服务器的实际url

private async void StartOAuth()
        {

            var authenticator = new OAuth2AuthenticatorEx("xamarin", string.Empty, "openid profile",
                new Uri("https://ipadress:5001/connect/authorize"), new Uri("com.companyname.SApp:/oauth2redirect"), new Uri("https://ipadress:5001/connect/token"), null, true);


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

            AuthenticationState.Authenticator = authenticator;

            var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
            Debug.WriteLine("after presenter");
            presenter.Login(authenticator);

            Debug.WriteLine($"Button StartOAuth clicked!");
        }
这是标识服务器的相应客户端

private static Client XamarinClient() => new Client
        {
            ClientId = "xamarin",
            ClientName = "Xamarin",

            AllowedGrantTypes = GrantTypes.Code,
            AllowAccessTokensViaBrowser = true,
            AlwaysIncludeUserClaimsInIdToken = true,

            RequireClientSecret = false,

            RequirePkce = true,

            AccessTokenType = AccessTokenType.Jwt,
            AccessTokenLifetime = 60,

            // Custom URL for native Apps. The URL below corresponds to bundle identifier 
            // on iOS and package name on Android 
            RedirectUris =
            {
                "com.companyname.SApp:/oauth2redirect",
            },

            AllowedScopes =
            { "openid", "profile" },
        };
忘记发布我的CustomUrlSchemeInterceptor活动:

using System;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using SApp.Services;

namespace OAuthNativeFlow.Droid
{
    [Activity(Label = "CustomUrlSchemeInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
    [IntentFilter(
        new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
        DataSchemes = new[] { "com.companyname.SApp" },
        DataPath = "/oauth2redirect")]
    public class CustomUrlSchemeInterceptorActivity : 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
            AuthenticationState.Authenticator.OnPageLoading(uri);

            Finish();
        }
    }
}
编辑:我将Uris改为http,并使用whireshark捕获服务器响应,该响应将触发重定向到应用程序中。这对我来说很好,但也许有帮助:

Frame 5009: 541 bytes on wire (4328 bits), 541 bytes captured (4328 bits) on interface 0
Ethernet II, Src: IntelCor_df:44:bd (28:16:ad:df:44:bd), Dst: Cisco_9f:f0:15 (00:00:0c:9f:f0:15)
Internet Protocol Version 4, Src: x.x.x.x, Dst: x.x.x.x
Transmission Control Protocol, Src Port: 5000, Dst Port: 38378, Seq: 9204, Ack: 4575, Len: 487
Hypertext Transfer Protocol
    HTTP/1.1 302 Found\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 302 Found\r\n]
        Response Version: HTTP/1.1
        Status Code: 302
        [Status Code Description: Found]
        Response Phrase: Found
    Date: Wed, 05 Jun 2019 07:55:06 GMT\r\n
    Server: Kestrel\r\n
    Content-Length: 0\r\n
        [Content length: 0]
     [truncated]Location: http://ipaddress:5000/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dxamarin%26redirect_uri%3Dcom.companyname.SApp%253A%252Foauth2redirect%26scope%3Dopenid%2520profile%26response_type%3Dcode
    \r\n
    [HTTP response 4/5]
    [Time since request: 0.079050000 seconds]
    [Prev request in frame: 4993]
    [Prev response in frame: 5002]
    [Request in frame: 5007]
    [Next request in frame: 5010]
    [Next response in frame: 5015]
    [Request URI [truncated]: http://ipaddress:5000/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dxamarin%26redirect_uri%3Dcom.companyname.SApp%253A%252Foauth2redirect%26scope%3Dopenid%2520profile%26response_type%3Dc]


更新1:好吧,在尝试了几件事情并与同事交谈之后,我想我至少已经确定identityserver不是问题的一部分。此外,我还必须使用https和前面提到的OAuth2Authenticator类的扩展,否则浏览器就不能重定向到应用程序。当我看到浏览器显示“您现在将被重定向”时,什么也没有发生。如果我手动关闭选项卡,OnAuthCompleted中的断点将触发,但EventArgs基本上为空(account为null,IsAuthenticated为false)。CustomUrlInterceptor中的断点从不触发,这可能意味着要么是我的重定向意图实现出了问题,要么是重定向uri本身出了问题。不幸的是,我没有主意了。我甚至尝试手动将以下内容添加到Manifest.xml中,这些内容取自Xamarin.Auth github:

<activity android:label="ActivityCustomUrlSchemeInterceptor"
    android:launchMode="singleTop" android:noHistory="true" android:name="md52ecc484fd43c6baf7f3301c3ba1d0d0c.ActivityCustomUrlSchemeInterceptor">
    <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:path="/oauth2redirect" />
      <data android:scheme="com.companyname.SApp" />
    </intent-filter>
  </activity>
一旦我这么做了,我就会
Xamarin.Auth.AuthException:Error authentication:invalid_grant
我仍在寻找突然获得无效_grant的原因,但浏览器无法将控制权返还给应用程序的主要问题仍然存在


另一个让我困惑的行为是,当我在应用程序关闭时执行上面的adb命令时,它会启动应用程序并立即向我显示一个屏幕,表明应用程序已停止工作。当我在浏览器的重定向屏幕上执行命令时(基本上是在应该发生重定向时强制重定向),我到达CustomUrlInterceptor中的断点,然后进入OnAuthError方法,然后应用程序关闭/崩溃。我明白为什么它在第一种情况下会崩溃,但在第二种情况下不会

在CustomUrlSchemeInterceptorActivity文件中将数据模式从“com.companyname.SApp”更改为您的Google重定向链接: 例子:
com.googleusercontent.apps.1093596514437-d3rpjj7clslhdg3uv365qpodsl5tq4fn

通常,重定向URL必须在OAuth服务网站上注册才能使用。有时,根据服务的不同,此URL的格式(http/https/custom schema)存在限制。我知道重定向URL注册正确了吗?从我刚才添加的服务器响应判断,我会说是的。当我解码响应的重定向url时,生成的uri看起来与我定义的重定向uri完全相同。你有没有找到解决方案?如果是这样,我很想知道,因为我遇到了同样的问题。
adb shell am start -a android.intent.action.VIEW -d "com.companyname.SApp:/oauth2redirect" com.companyname.SApp