What error do you get when you use it in the shared project?
There is no built-in solution to exclude specific permission from the permission list created by the roles union.
If you are using a user-specific permission system, I would recommend re-designing your roles and using user permissions instead of roles.
6.9 public-web 【PublicWeb】
{ "App": { "SelfUrl": "https://public-web" }, ... "RemoteServices": { "Default": { "BaseUrl": "https://public-web/" -> should be http://public-gate } },
Public-Web application RemoteService should be Public-Web-Gateway, not itself.
Share the application logs please.
I don't know if it is related to it but:
I think you are using it behind reverse proxy since you seem to have configured ForwardedHeadersOptions but not used the midware at OnApplicationInitialization:
...
app.UseForwardedHeaders();
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();
Is the product service up and running when you run abp generate-proxy -t ng?
[13:32:17 ERR] An unhandled exception has occurred while executing the request. 2022-03-30 19:02:17 at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService) 2022-03-30 19:02:17 at IdentityServer4.Endpoints.DiscoveryEndpoint.ProcessAsync(HttpContext context) 2022-03-30 19:02:17 at IdentityServer4.ResponseHandling.DiscoveryResponseGenerator.CreateDiscoveryDocumentAsync(String baseUrl, String issuerUri) 2022-03-30 19:02:17 at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection) 2022-03-30 19:02:17 at System.Linq.Enumerable.SelectArrayIterator2.MoveNext() 2022-03-30 19:02:17 at x973ltTuyr0iNFtkVC2.uoxoRDTMlI1EVNyvYXa.O5QlTBeshI(Int32 ) 2022-03-30 19:02:17 System.Exception: Exception of type 'System.Exception' was thrown. 2022-03-30 19:02:17 [13:32:17 FTL] Unhandled exception: Exception of type 'System.Exception' was thrown. 2022-03-30 19:02:17 [13:32:17 INF] {"Details": "System.Exception: Exception of type 'System.Exception' was thrown.\n at x973ltTuyr0iNFtkVC2.uoxoRDTMlI1EVNyvYXa.O5QlTBeshI(Int32 )\n at System.Linq.Enumerable.SelectArrayIterator2.MoveNext()\n at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection)\n at IdentityServer4.ResponseHandling.DiscoveryResponseGenerator.CreateDiscoveryDocumentAsync(String baseUrl, String issuerUri)\n at IdentityServer4.Endpoints.DiscoveryEndpoint.ProcessAsync(HttpContext context)\n at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)", "Category": "Error", "Name": "Unhandled Exception", "EventType": "Error", "Id": 3000, "Message": "Exception of type 'System.Exception' was thrown.", "ActivityId": "0HMGI9DB2HCV5:00000002", "TimeStamp": "2022-03-30T13:32:17.0000000Z", "ProcessId": 1, "LocalIpAddress": "::ffff:10.244.2.49:80", "RemoteIpAddress": "202.131.101.34", "$type": "UnhandledExceptionEvent"}
This seems an error from IdentityServerMiddleware but I have no idea what causes it.
Can you share your AuthServerModule?
We would like to understand the http request flow between Web(MVC UI) Layer and WebGateway.
From the microservice solution perspective, WebUI (I am assuming you mean public-web application) is not a layer but an application.
Can you please provide more details on communication between WebUI & WebGateway (for http requests) and relevant code which passes Barer token etc...
I think you want to learn generally how the proxying works; how an HTTP request is done, headers are set and forwarded; not just microservice specific. So I will try to explain better.
Your request is created by ClientProxyBase (or DynamicHttpProxyInterceptor if you are using dynamic proxying):
protected IRemoteServiceHttpClientAuthenticator ClientAuthenticator => LazyServiceProvider.LazyGetRequiredService<IRemoteServiceHttpClientAuthenticator>();
protected virtual async Task<HttpContent> RequestAsync(ClientProxyRequestContext requestContext)
{
...
// Gets the remote service configuration
RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName);
// Creates the HttpClient service configuration
var client = HttpClientFactory.Create(clientConfig.RemoteServiceName);
...
// Authentication headers are forwarded or set in here based on remoteServiceConfig
if (requestContext.Action.AllowAnonymous != true)
{
await ClientAuthenticator.Authenticate(
new RemoteServiceHttpClientAuthenticateContext(
client,
requestMessage,
remoteServiceConfig,
clientConfig.RemoteServiceName
)
);
}
...
}
IRemoteServiceHttpClientAuthenticator is implemented by:
await IdentityModelAuthenticationService.TryAuthenticateAsync(
context.Client,
context.RemoteService.GetIdentityClient() ?? context.RemoteServiceName
);
Uses IdentityModelAuthenticationService to authenticate the service as below:
public async Task<bool> TryAuthenticateAsync(
[NotNull] HttpClient client,
string identityClientName = null)
{
var accessToken = await GetAccessTokenOrNullAsync(identityClientName);
if (accessToken == null)
{
return false;
}
SetAccessToken(client, accessToken);
return true;
}
protected virtual void SetAccessToken(HttpClient client, string accessToken)
{
//TODO: "Bearer" should be configurable
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}
IdentityModelRemoteServiceHttpClientAuthenticator and handles authentication when HTTP context is available (For UI based applications like Razor/MVC):public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
{
if (context.RemoteService.GetUseCurrentAccessToken() != false)
{
var accessToken = await GetAccessTokenFromHttpContextOrNullAsync();
if (accessToken != null)
{
context.Request.SetBearerToken(accessToken);
return;
}
}
await base.Authenticate(context);
}
protected virtual async Task<string> GetAccessTokenFromHttpContextOrNullAsync()
{
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext == null)
{
return null;
}
return await httpContext.GetTokenAsync("access_token");
}
IdentityModelRemoteServiceHttpClientAuthenticator and uses IAccessTokenProvider for getting/setting authorization headers for blazor applications.Basically, how to set the authorization header is based on application type;
Volo.Abp.Http.Client.IdentityModel moduleVolo.Abp.Http.Client.IdentityModel.Web moduleVolo.Abp.Http.Client.IdentityModel.WebAssembly moduleTry using IOrganizationUnitAppService under the IdentityPro module namespace.