Hello,
I am working on developing with the ABP Studio microservice template and have a few questions on expected setup for new microservices. I have generated a basic setup using the microservice template (EF Core, MVC, no mobile UI). I follow the add new microservice (EF Core) option here: I get this initial layout:
It doesn’t seem like these microservice templates have proxy support by default (C# or JS). I would like to add this functionality in but have been struggling with how it should be added and what is required for full functionality.
I suspect that we would want to add some dependencies or setup code to the MyServiceModule and MyServiceContractsModule that mimics the HttpApi and HttpApi.Client from the DDD services in the past. I couldn’t glean any information from the other services because they seem to rely on full DDD components through library references.
I was able to generate a static JS proxy but could not understand the correct auth flow it required to work against an authorized endpoint. I could not get the C# proxies to properly generate at all (static or dynamic.)
A few things I would like clarified:
- What is the minimum implementation to enable proxies (C#, JS, static and dynamic) in the new microservice service template? (I would like to avoid using more project layers than what already exists, this defeats the purpose of using the simpler service template) - What is required for the Web project to use both the C# proxy through MVC razor and the JS proxy through a web page directly? - Is anything required for the gateway? - What is required for proper auth flows using both proxies?
Thanks!
I have an existing module project that I have built to be a remote service. I am creating a web application project to be the main site. The setup I am going for is the web project has the web application and Identity Server setup, and the module project acts as a remote API that the web project accesses.
My module is in a separate solution and runs via a host project (the one that is generated by the CLI tool). I have removed Identity Server from this solution and would like the module to rely on the Identity Server host in my web project solution. The module handles its own migrations through the host project and has a separate DB from the web project.
For some reason I am struggling to get the dynamic C# client for the module to work in the web project across an authorized API call. I have no problems using it with unauthorized API endpoints. It is giving me a 401 unauthorized response when I attempt to access authorized endpoints. Below I have detailed the setup from a blank project of my web application in hopes of finding where I am going wrong.
Below is my process to create this issue:
"RemoteServices": {
"Devices": {
"BaseUrl": "https://localhost:44375"
}
},
Devices.cshtml
@page
@model NowMicro.Dice.Portal.Web.Pages.DevicesModel
<h2>Device Test</h2>
@{ var device = Model.Device; }
<p>Serial Number: </p>
@device.SerialNumber;
DevicesModel.cs
using Microsoft.AspNetCore.Authorization;
using NowMicro.Dice.Devices.Authorization;
using NowMicro.Dice.Devices.DtoModels;
using NowMicro.Dice.Devices.ServiceInterfaces;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
namespace NowMicro.Dice.Portal.Web.Pages
{
public class DevicesModel : AbpPageModel
{
public DeviceDto Device { get; set; }
private readonly IDevicesAppService _devicesAppService;
private readonly IAuthorizationService _authorization;
public DevicesModel(IDevicesAppService devicesAppService, IAuthorizationService authorization)
{
_devicesAppService = devicesAppService;
_authorization = authorization;
}
public async Task OnGetAsync()
{
if (!await _authorization.IsGrantedAsync(DevicesPermissions.Devices.Default))
{
Redirect("/");
}
Device = await _devicesAppService.GetAsync("string");
}
}
}
typeof(DevicesHttpApiClientModule)
which is the HttpApiClient module for the remote API module.[FTL] Host terminated unexpectedly!
System.IO.FileNotFoundException: Could not load file or assembly 'Volo.Abp.Http.Client, Version=2.6.2.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
2020-05-05 13:17:23.894 -05:00 [INF] Executed endpoint '/Devices'
2020-05-05 13:17:23.903 -05:00 [DBG] Added 0 entity changes to the current audit log
2020-05-05 13:17:23.903 -05:00 [DBG] Added 0 entity changes to the current audit log
2020-05-05 13:17:23.904 -05:00 [INF] Request finished in 4369.7582ms 500 application/json; charset=utf-8
2020-05-05 13:17:52.985 -05:00 [INF] Request starting HTTP/2.0 GET https://localhost:44353/devices
2020-05-05 13:17:23.894 -05:00 [INF] Executed page /Devices in 4347.7692ms
2020-05-05 13:17:52.988 -05:00 [INF] Executing endpoint '/Devices'
2020-05-05 13:17:52.989 -05:00 [INF] Route matched with {page = "/Devices", controller = "", area = "", action = ""}. Executing page /Devices
2020-05-05 13:17:52.991 -05:00 [INF] Executing handler method NowMicro.Dice.Portal.Web.Pages.DevicesModel.OnGetAsync - ModelState is "Valid"
2020-05-05 13:17:52.991 -05:00 [DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:5a86407f-aa6f-3eab-147a-39f4f7773384,n:Devices.Device
2020-05-05 13:17:52.991 -05:00 [DBG] Found in the cache: pn:U,pk:5a86407f-aa6f-3eab-147a-39f4f7773384,n:Devices.Device
2020-05-05 13:17:52.991 -05:00 [DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:Devices.Device
2020-05-05 13:17:52.991 -05:00 [DBG] Found in the cache: pn:R,pk:admin,n:Devices.Device
2020-05-05 13:17:52.992 -05:00 [INF] Authorization was successful.
2020-05-05 13:17:52.992 -05:00 [INF] Start processing HTTP request GET "https://localhost:44375/api/abp/api-definition"
2020-05-05 13:17:52.992 -05:00 [INF] Sending HTTP request GET "https://localhost:44375/api/abp/api-definition"
2020-05-05 13:17:53.244 -05:00 [INF] Received HTTP response after 248.9889ms - "OK"
2020-05-05 13:17:53.244 -05:00 [INF] End processing HTTP request after 252.0985ms - "OK"
2020-05-05 13:17:53.283 -05:00 [INF] Start processing HTTP request GET "https://localhost:44375/api/devices?serialNumber=string&api-version=1.0"
2020-05-05 13:17:53.293 -05:00 [INF] Sending HTTP request GET "https://localhost:44375/api/devices?serialNumber=string&api-version=1.0"
2020-05-05 13:17:53.366 -05:00 [INF] Received HTTP response after 73.2875ms - "Unauthorized"
2020-05-05 13:17:53.370 -05:00 [INF] End processing HTTP request after 86.7997ms - "Unauthorized"
2020-05-05 13:17:53.452 -05:00 [ERR] ---------- RemoteServiceErrorInfo ----------
2020-05-05 13:17:53.452 -05:00 [ERR] {
"code": null,
"message": "An internal error occurred during your request!",
"details": null,
"validationErrors": null
}
2020-05-05 13:17:53.452 -05:00 [ERR] Remote service returns error! HttpStatusCode: Unauthorized, ReasonPhrase: Unauthorized
Volo.Abp.AbpException: Remote service returns error! HttpStatusCode: Unauthorized, ReasonPhrase: Unauthorized
at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1.ThrowExceptionForResponseAsync(HttpResponseMessage response)
at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1.MakeRequestAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1.MakeRequestAndGetResultAsync[T](IAbpMethodInvocation invocation)
at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1.GetResultAsync(Task task, Type resultType)
at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor`1.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at NowMicro.Dice.Portal.Web.Pages.DevicesModel.OnGetAsync() in C:\Users\hilto\Source\repos\DICE\Modules\NowMicro.Dice.Portal\src\NowMicro.Dice.Portal.Web\Pages\Devices.cshtml.cs:line 29
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
2020-05-05 13:17:53.453 -05:00 [INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'.
2020-05-05 13:17:53.454 -05:00 [INF] Executed page /Devices in 464.5444ms
2020-05-05 13:17:53.454 -05:00 [INF] Executed endpoint '/Devices'
2020-05-05 13:17:53.463 -05:00 [DBG] Added 0 entity changes to the current audit log
2020-05-05 13:17:53.463 -05:00 [DBG] Added 0 entity changes to the current audit log
2020-05-05 13:17:53.463 -05:00 [INF] Request finished in 477.7475ms 500 application/json; charset=utf-8
Here are the coinciding logs from the module host:
2020-05-05 13:17:53.301 -05:00 [INF] Request starting HTTP/1.1 GET https://localhost:44375/api/devices?serialNumber=string&api-version=1.0
2020-05-05 13:17:53.302 -05:00 [DBG] AuthenticationScheme: Bearer was not authenticated.
2020-05-05 13:17:53.309 -05:00 [INF] Authorization failed.
2020-05-05 13:17:53.364 -05:00 [INF] AuthenticationScheme: BearerIdentityServerAuthenticationJwt was challenged.
2020-05-05 13:17:53.365 -05:00 [INF] AuthenticationScheme: Bearer was challenged.
2020-05-05 13:17:53.365 -05:00 [INF] Request finished in 63.8403ms 401
I’ve had no luck in figuring out why I continue to get unauthorized results. Any help in deciphering this is much appreciated. Let me know if you need any more information from me.