Starts in:
2 DAYS
4 HRS
42 MIN
26 SEC
Starts in:
2 D
4 H
42 M
26 S

Activities of "alin.andersen"

I added the network_security_config.xml file like this:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
	<domain-config cleartextTrafficPermitted="true">
		<domain includeSubdomains="true">192.168.0.103</domain>
	</domain-config>
</network-security-config>

And added android:networkSecurityConfig="@xml/network_security_config" to the application in the AndroidManifest.xml, but I still the the SSL exception.

I also tried setting the ServicePointManager.ServerCertificateValidationCallback to (x1, x2, x3, x4) => true, but does not help I still get the same SSL exception.

I also tried adding android:usesCleartextTraffic="true" to the application in the AndroidManifest.xml.

And I tried to change the HttpClient implementation in the Android project, but still get the SSL exception.

Can you check api gateway ocelot configuration? Change DownstreamScheme of your product routing to http if you are hosting product service on http.

Good idea, I added the change, but we still get the same SSL exception. Gateway logs are empty, so the client application does not even reach the gateway.

This is the appsettings file for web-gateway:

{
      "DownstreamPathTemplate": "/api/product-service/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44361
        }
      ],
      "UpstreamPathTemplate": "/api/product-service/{everything}",
      "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ]
    }

Your client (Xamarin-Forms) trying to make a request to Api Resource (IProductAppService) which is Http.Api.Host (.Net Core application) project. You are getting SSL error because Api Resource (.Net Core app) only allows https.

So you need set Api Resource to allow http also as the configuration above.

Thanks for the clarification. Currently we access the API Resources through the web-gateway gateway.

This is our appsettings file in the API Resource project ProductService.HttpApi.Host:

"AuthServer": {
    "Authority": "https://localhost:44322",
    "RequireHttpsMetadata": "false"
},

We also added this to the appsettings file for the web-gateway gateway:

"AuthServer": {
    "Authority": "https://localhost:44322",
    "RequireHttpsMetadata": "false",
    "SwaggerClientId": "WebGateway_Swagger",
    "SwaggerClientSecret": "1q2w3e*"
},

On the Xamarin-Forms client we have this module:

public class Module : AbpModule
{
    public static string AccessToken { get; set; } // This is set when the browser returns the access token.

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var services = context.Services;

        services.Configure<AbpHttpClientBuilderOptions>(options =>
        {
            options.ProxyClientActions.Add((name, p, c) =>
            {
                c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
            });
        });

        services.Configure<AbpRemoteServiceOptions>(options =>
        {
            options.RemoteServices.Default = new RemoteServiceConfiguration(Constants.BaseUrl); // URL of the Web-Gateway
        });
   services.AddHttpClientProxies(typeof(ProductServiceApplicationContractsModule).Assembly);
    }
}

Then we resolve for the IProductAppService in the Xamarin-Forms project and try to call the GetListAsync method:

try
{
    var t = await _productAppService.GetListAsync(new GetProductsInput());
}
catch (Exception ex)
{

}

We get this exception:

"The SSL connection could not be established, see inner exception."
  at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore (System.IO.Stream stream, System.Net.Security.SslClientAuthenticationOptions sslOptions, System.Threading.CancellationToken cancellationToken) [0x000f6] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs:176 
  at System.Threading.Tasks.ValueTask`1[TResult].get_Result () [0x0001b] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/Common/src/CoreLib/System/Threading/Tasks/ValueTask.cs:813 
  at System.Net.Http.HttpConnectionPool.CreateConnectionAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x002d8] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs:408 
  at System.Threading.Tasks.ValueTask`1[TResult].get_Result () [0x0001b] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/Common/src/CoreLib/System/Threading/Tasks/ValueTask.cs:813 
  at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync (System.Threading.Tasks.ValueTask`1[TResult] creationTask) [0x000a2] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs:543 
  at System.Threading.Tasks.ValueTask`1[TResult].get_Result () [0x0001b] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/Common/src/CoreLib/System/Threading/Tasks/ValueTask.cs:813 
  at System.Net.Http.HttpConnectionPool.SendWithRetryAsync (System.Net.Http.HttpRequestMessage request, System.Boolean doRequestAuth, System.Threading.CancellationToken cancellationToken) [0x0003f] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs:284 
  at System.Net.Http.RedirectHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x00070] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs:32 
  at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x000d7] in <831b7afb4f024d399aa7f21c2ef99b9c>:0 
  at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x000ef] in <831b7afb4f024d399aa7f21c2ef99b9c>:0 
  at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task`1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) [0x0017e] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:506 
  at Volo.Abp.Http.Client.DynamicProxying.ApiDescriptionFinder.GetApiDescriptionFromServerAsync (System.Net.Http.HttpClient client, System.String baseUrl) [0x0006d] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\ApiDescriptionFinder.cs:109 
  at Volo.Abp.Http.Client.DynamicProxying.ApiDescriptionCache.GetAsync (System.String baseUrl, System.Func`1[TResult] factory) [0x000eb] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\ApiDescriptionCache.cs:34 
  at Volo.Abp.Http.Client.DynamicProxying.ApiDescriptionFinder.GetApiDescriptionAsync (System.Net.Http.HttpClient client, System.String baseUrl) [0x0006c] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\ApiDescriptionFinder.cs:90 
  at Volo.Abp.Http.Client.DynamicProxying.ApiDescriptionFinder.FindActionAsync (System.Net.Http.HttpClient client, System.String baseUrl, System.Type serviceType, System.Reflection.MethodInfo method) [0x00034] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\ApiDescriptionFinder.cs:46 
  at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1[TService].GetActionApiDescriptionModel (Volo.Abp.DynamicProxy.IAbpMethodInvocation invocation) [0x0012d] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\DynamicHttpProxyInterceptor.cs:82 
  at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1[TService].InterceptAsync (Volo.Abp.DynamicProxy.IAbpMethodInvocation invocation) [0x0003c] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\DynamicHttpProxyInterceptor.cs:55 
  at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1[TInterceptor].InterceptAsync[TResult] (Castle.DynamicProxy.IInvocation invocation, Castle.DynamicProxy.IInvocationProceedInfo proceedInfo, System.Func`3[T1,T2,TResult] proceed) [0x00059] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:29 
  at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult] (Castle.DynamicProxy.IInvocation invocation, Castle.DynamicProxy.IInvocationProceedInfo proceedInfo) [0x00079] in <25225aa189ef4d0091cfe671f9159d35>:0 
  at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1[TResult].ProceedAsync () [0x00038] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:24 
  at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync (Volo.Abp.DynamicProxy.IAbpMethodInvocation invocation) [0x0009c] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Validation\Volo\Abp\Validation\ValidationInterceptor.cs:19 
  at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1[TInterceptor].InterceptAsync[TResult] (Castle.DynamicProxy.IInvocation invocation, Castle.DynamicProxy.IInvocationProceedInfo proceedInfo, System.Func`3[T1,T2,TResult] proceed) [0x00059] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:29 

The configuration did not change the SSL validation. We think the local HTTP client rejects the connection, because the web-gateway does not output any logs when trying to connect.

You can disable the SSL from API resource appsettings you are trying to make request to:

"AuthServer": { 
    "Authority": "https://idsrvHost", 
    "RequireHttpsMetadata": "false", // -> true by default 
  }, 

This again seems to be for an ASP-NET Core application (appsettings.json). How does this work on Xamarin-Forms? Can I configure the "RequireHttpsMetadata" programmatically, instead from a configuration file?

There is also a community post from one of the community members: Consume ABP API from Xamarin App. Maybe it can help.

I read the tutorial you posted. Essentially the authentication call is made directly in the app via the HttpClient and then the access token is stored locally. But the access token is never used in combination with the dynamic HTTP proxies. How do I get the HTTP client proxies to use an access token I retrieved from the OIDC client and disable SSL for testing purposes?

services.AddHttpClientProxies(typeof(ProductServiceApplicationContractsModule).Assembly);

Thanks for the quick answer.

But the configuration section you posted is for the "Synchronous Communication between Microservices". However, I have an Xamarin-Forms application that is running on the users phone. In our workflow the app opens the browser for the user to perform the authentication (auth-server). The app then retrieves an access token. This is already working as expected so no problems here.

The ABP module I posted is running on the Xamarin-Forms application on the user side, because we would like to use the app services (e.g. IProductAppService) directly in the app. Is this possible? Or is it not supposed to be used on the client side like that. The mobile app should access the API gateway with this access token.

Thanks for the help.

Hi,

we are running an Xamarin-Forms app and we currently authenticate the app using an OIDC client. We are able to retrieve the access token from the auth-server (ABP Commercial).

We want to use the IProductAppService as an example on the mobile app. We created a AbpModule on the app that depends on the following modules: AbpAutofacModule, AbpHttpClientModule and ProductServiceApplicationContractsModule.

[DependsOn(
    typeof(AbpAutofacModule),
    typeof(AbpHttpClientModule),
    typeof(ProductServiceApplicationContractsModule)
    )]
public class Module : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var services = context.Services;

        services.Configure<AbpHttpClientBuilderOptions>(options =>
        {
            options.ProxyClientActions.Add((name, p, c) =>
            {
                c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", HeadersHandler.AccessToken);
            });
        });

        services.AddScoped<IHttpClientFactory>(s => new OurHttpClientFactory()));

        services.Configure<AbpRemoteServiceOptions>(options =>
        {
            options.RemoteServices.Default = new RemoteServiceConfiguration(Constants.BaseUrl);
        });

        services.AddHttpClientProxies(typeof(ProductServiceApplicationContractsModule).Assembly);
    }
}

Then we resolve for the service IProductAppService. The service is returned successfully.

Now, here are our problems:

1) When calling a method from the IProductAppService we get: System.Net.Http.HttpRequestException: The SSL connection could not be established.

We want to override the IHttpClientFactory that is consumed by the dynamic proxies so that we can disable the SSL validation on the mobile app side on the HttpClient.

We tried to add our implementation of the IHttpClientFactory interface in the module:

services.AddScoped<IHttpClientFactory>(s => new OurHttpClientFactory()));

But when we resolve the IProductAppService service, we received this exception:

Object reference not set to an instance of an object.

  at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1[TService].get_ClientOptions () [0x00000] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\ClientProxying\ClientProxyBase.cs:36 
  at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1[TService].RequestAsync (Volo.Abp.Http.Client.ClientProxying.ClientProxyRequestContext requestContext) [0x00030] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\ClientProxying\ClientProxyBase.cs:108 
  at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1[TService].RequestAsync[T] (Volo.Abp.Http.Client.ClientProxying.ClientProxyRequestContext requestContext) [0x0003d] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\ClientProxying\ClientProxyBase.cs:76 
  at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptorClientProxy`1[TService].CallRequestAsync[T] (Volo.Abp.Http.Client.ClientProxying.ClientProxyRequestContext requestContext) [0x0002d] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\DynamicHttpProxyInterceptorClientProxy.cs:11 
  at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1[TService].CallRequestAsync[T] (Volo.Abp.Http.Client.ClientProxying.ClientProxyRequestContext context) [0x00032] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\DynamicHttpProxyInterceptor.cs:92 
  at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1[TService].GetResultAsync (System.Threading.Tasks.Task task, System.Type resultType) [0x0001f] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\DynamicHttpProxyInterceptor.cs:97 
  at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1[TService].InterceptAsync (Volo.Abp.DynamicProxy.IAbpMethodInvocation invocation) [0x001a2] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Http.Client\Volo\Abp\Http\Client\DynamicProxying\DynamicHttpProxyInterceptor.cs:71 
  at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1[TInterceptor].InterceptAsync[TResult] (Castle.DynamicProxy.IInvocation invocation, Castle.DynamicProxy.IInvocationProceedInfo proceedInfo, System.Func`3[T1,T2,TResult] proceed) [0x00059] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:29 
  at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult] (Castle.DynamicProxy.IInvocation invocation, Castle.DynamicProxy.IInvocationProceedInfo proceedInfo) [0x00079] in &lt;25225aa189ef4d0091cfe671f9159d35&gt;:0 
  at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1[TResult].ProceedAsync () [0x00038] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAbpMethodInvocationAdapterWithReturnValue.cs:24 
  at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync (Volo.Abp.DynamicProxy.IAbpMethodInvocation invocation) [0x0009c] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Validation\Volo\Abp\Validation\ValidationInterceptor.cs:19 
  at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1[TInterceptor].InterceptAsync[TResult] (Castle.DynamicProxy.IInvocation invocation, Castle.DynamicProxy.IInvocationProceedInfo proceedInfo, System.Func`3[T1,T2,TResult] proceed) [0x00059] in D:\ci\Jenkins\workspace\abp-commercial-release\abp\framework\src\Volo.Abp.Castle.Core\Volo\Abp\Castle\DynamicProxy\CastleAsyncAbpInterceptorAdapter.cs:29 

So it is probably not intended to be used like this. How can we supply our own HttpClient. We need to set the HttpClientHandler of the HttpClient so that we can set the following (only for Debugging):

ServerCertificateCustomValidationCallback = DangerousAcceptAnyServerCertificateValidator;

2) How can we add the access token to the headers of the HttpClient consumed by the dynamic proxies?

This is our current solution:

services.Configure<AbpHttpClientBuilderOptions>(options =>
{
    options.ProxyClientActions.Add((name, p, c) =>
    {
        c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<ACCESS-TOKEN>");
    });
});

Is this the recommended way or is there a better solution?

Showing 41 to 47 of 47 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06