Open Closed

v8.0.0 Permission issue #6432


User avatar
0
yilmaz.132 created
  • ABP Framework version: v8.0.0
  • UI Type: MVC
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC): yes
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

We use the commercial microservice solution. After upgrading to v8.0.0, we receive authorization errors at the identity and identityserver endpoints in the IdentityService service. When I checked the logs of other services, I noticed that it could not read user and role permissions.

We use Identity Server in AuthServer.

IdentityServiceModule.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Retina.IdentityService.DbMigrations;
using Retina.IdentityService.EntityFramework;
using Retina.Shared.Hosting.Microservices;
using Prometheus;
using Volo.Abp;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
using Microsoft.AspNetCore.Authentication.Twitter;
using Microsoft.Extensions.Configuration;
using Retina.Shared.Hosting.AspNetCore.HealthChecks;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Auditing;
using Volo.Abp.Security.Claims;

namespace Retina.IdentityService
{
    [DependsOn(
        typeof(RetinaSharedHostingMicroservicesModule),
        typeof(IdentityServiceEntityFrameworkCoreModule),
        typeof(IdentityServiceApplicationModule),
        typeof(IdentityServiceHttpApiModule)
    )]
    public class IdentityServiceHttpApiHostModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            // Enable if you need these
            var configuration = context.Services.GetConfiguration();
            // var hostingEnvironment = context.Services.GetHostingEnvironment();

            JwtBearerConfigurationHelper.Configure(context, "IdentityService");
            SwaggerConfigurationHelper.Configure(context, "Identity Service API");
            context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
            {
                options.IsDynamicClaimsEnabled = true;
            });
            Configure<AbpAspNetCoreMvcOptions>(options => { options.ExposeIntegrationServices = true; });
            ConfigureAuditLogs();
            ConfigureHealthChecks(context.Services, configuration);
            ConfigureExternalProviders(context);
        }

        private void ConfigureHealthChecks(IServiceCollection services, IConfiguration configuration)
        {
            services.AddRetinaHealthChecks("Identity Api", configuration["ConnectionStrings:IdentityService"]);
        }

        private void ConfigureAuditLogs()
        {
            Configure<AbpAuditingOptions>(options => { options.ApplicationName = "Identity Service"; });
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCorrelationId();
            app.UseAbpRequestLocalization();
            app.UseAbpSecurityHeaders();
            app.UseStaticFiles();
            app.UseRouting();
            // app.UseCors();
            app.UseHttpMetrics();
            app.UseAuthentication();
            app.UseAbpClaimsMap();
            app.UseMultiTenancy();
            app.UseUnitOfWork();
            app.UseDynamicClaims();
            app.UseAuthorization();
            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "Identity Service API");
            });
            app.UseAbpSerilogEnrichers();
            app.UseAuditing();
            app.UseConfiguredEndpoints(endpoints => { endpoints.MapMetrics(); });
        }

        public async override Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context)
        {
            var env = context.GetEnvironment();

            // if (!env.IsDevelopment())
            // {
            using (var scope = context.ServiceProvider.CreateScope())
            {
                await scope.ServiceProvider
                    .GetRequiredService<IdentityServiceDatabaseMigrationChecker>()
                    .CheckAndApplyDatabaseMigrationsAsync();
            }
            // }
        }

        private void ConfigureExternalProviders(ServiceConfigurationContext context)
        {
            context.Services
                .AddDynamicExternalLoginProviderOptions<GoogleOptions>(
                    GoogleDefaults.AuthenticationScheme,
                    options =>
                    {
                        options.WithProperty(x => x.ClientId);
                        options.WithProperty(x => x.ClientSecret, isSecret: true);
                    }
                )
                .AddDynamicExternalLoginProviderOptions<MicrosoftAccountOptions>(
                    MicrosoftAccountDefaults.AuthenticationScheme,
                    options =>
                    {
                        options.WithProperty(x => x.ClientId);
                        options.WithProperty(x => x.ClientSecret, isSecret: true);
                    }
                )
                .AddDynamicExternalLoginProviderOptions<TwitterOptions>(
                    TwitterDefaults.AuthenticationScheme,
                    options =>
                    {
                        options.WithProperty(x => x.ConsumerKey);
                        options.WithProperty(x => x.ConsumerSecret, isSecret: true);
                    }
                );
        }
    }
}

AuthServerModule.cs

using System;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Retina.AdministrationService.EntityFrameworkCore;
using Retina.IdentityService.EntityFramework;
using Retina.SaasService.EntityFramework;
using Retina.Shared.Hosting.AspNetCore;
using Prometheus;
using StackExchange.Redis;
using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.Auditing;
using Volo.Abp.BackgroundJobs.RabbitMQ;
using Volo.Abp.Caching;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Emailing;
using Volo.Abp.EventBus.RabbitMq;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.UI.Navigation.Urls;
using Volo.Abp.VirtualFileSystem;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Net;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System.Security.Claims;
using Volo.Abp.IdentityServer;
using IdentityServer4.Configuration;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using Microsoft.IdentityModel.Logging;
using Volo.Abp.Account.Public.Web;
using Microsoft.Extensions.Configuration;
using IdentityServer4.Extensions;
using System.Collections.Generic;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
using Microsoft.AspNetCore.Authentication.Twitter;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Identity.Web;
using Retina.Shared.Hosting.AspNetCore.HealthChecks;
using Volo.Abp.Account.Public.Web.ExternalProviders;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling;
using Volo.Abp.LeptonX.Shared;
using Volo.Abp.Security.Claims;

namespace Retina.AuthServer
{
    [DependsOn(
        typeof(AbpCachingStackExchangeRedisModule),
        typeof(AbpEventBusRabbitMqModule),
        typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
        typeof(AbpBackgroundJobsRabbitMqModule),
        typeof(AbpAccountPublicWebIdentityServerModule),
        typeof(AbpAccountPublicApplicationModule),
        typeof(AbpAccountPublicHttpApiModule),
        typeof(AdministrationServiceEntityFrameworkCoreModule),
        typeof(IdentityServiceEntityFrameworkCoreModule),
        typeof(SaasServiceEntityFrameworkCoreModule),
        typeof(RetinaSharedHostingAspNetCoreModule),
        typeof(RetinaSharedLocalizationModule),
        typeof(AbpAccountAdminApplicationModule),
        typeof(AbpAccountAdminHttpApiModule)
    )]
    public class RetinaAuthServerModule : AbpModule
    

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

            var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();

            app.Use(async (ctx, next) =>
            {
                ctx.Request.Scheme = "https";
                if (ctx.Request.Headers.ContainsKey("from-ingress"))
                {
                    ctx.SetIdentityServerOrigin(configuration["App:SelfUrl"]);
                }

                if (ctx.Request.Path.StartsWithSegments("/robots.txt"))
                {
                    var robotsTxtPath = Path.Combine(env.ContentRootPath, "robots.txt");
                    string output = "User-agent: *  \nDisallow: /";
                    if (File.Exists(robotsTxtPath))
                    {
                        output = await File.ReadAllTextAsync(robotsTxtPath);
                    }

                    ctx.Response.ContentType = "text/plain";
                    await ctx.Response.WriteAsync(output);
                }
                else
                {
                    await next();
                }
            });

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAbpRequestLocalization();

            if (!env.IsDevelopment())
            {
                app.UseErrorPage();
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseCorrelationId();
            app.UseAbpSecurityHeaders();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCors(DefaultCorsPolicyName);
            app.UseCookiePolicy();
            app.UseHttpMetrics();
            app.UseAuthentication();
            app.UseJwtTokenMiddleware();
            app.UseMultiTenancy();
            app.UseAbpSerilogEnrichers();
            app.UseUnitOfWork();
            app.UseDynamicClaims();
            app.UseIdentityServer();
            app.UseAuthorization();
            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "Account Service API");
                options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
                options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]);
            });
            app.UseAuditing();
            app.UseConfiguredEndpoints(endpoints => { endpoints.MapMetrics(); });
        }

        private void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration)
        {
            SwaggerConfigurationHelper.ConfigureWithAuth(
                context: context,
                authority: configuration["AuthServer:Authority"],
                scopes: new Dictionary<string, string>
                {
                    /* Requested scopes for authorization code request and descriptions for swagger UI only */
                    { "AuthServer", "Account Service API" }
                },
                apiTitle: "Account Service API"
            );
        }
    }
}

[identity-service_3e0e16ed-9]: [11:19:20 DBG] PermissionStore.GetCacheItemAsync: pn:C,pk:Retina_Web,n:AbpIdentity.OrganizationUnits [identity-service_3e0e16ed-9]: [11:19:20 DBG] Found in the cache: pn:C,pk:Retina_Web,n:AbpIdentity.OrganizationUnits

As seen here, it does not see the caches in the Role and User providers.

But other services work with the same configurations. But there is such an error in the IdentityService service. I would like your support in solving it.


15 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share the full logs? liming.ma@volosoft.com

    Have you tested this case in a new microservice template project?

  • User Avatar
    0
    yilmaz.132 created

    Hi,

    I sent you the log files by e-mail.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can try to remove the app.UseDynamicClaims from the ASP NET Core pipeline.

    https://docs.abp.io/en/abp/latest/Dynamic-Claims

    [auth-server_9fe7f5b1-5]: [21:50:00 ERR] ---------- RemoteServiceErrorInfo ----------
    [auth-server_9fe7f5b1-5]: {
    [auth-server_9fe7f5b1-5]: "code": null,
    [auth-server_9fe7f5b1-5]: "message": "An internal error occurred during your request!",
    [auth-server_9fe7f5b1-5]: "details": null,
    [auth-server_9fe7f5b1-5]: "data": {},
    [auth-server_9fe7f5b1-5]: "validationErrors": null
    [auth-server_9fe7f5b1-5]: }
    [auth-server_9fe7f5b1-5]:
    [auth-server_9fe7f5b1-5]: [21:50:00 ERR] Nullable object must have a value.
    [auth-server_9fe7f5b1-5]: System.InvalidOperationException: Nullable object must have a value.
    [auth-server_9fe7f5b1-5]: at System.Nullable`1.get_Value()
    [auth-server_9fe7f5b1-5]: at Volo.Abp.Users.CurrentUserExtensions.GetId(ICurrentUser currentUser)
    [auth-server_9fe7f5b1-5]: at Volo.Abp.Account.DynamicClaimsAppService.RefreshAsync()```
    
  • User Avatar
    0
    yilmaz.132 created

    Do I need to remove app.UseDynamicClaims from all service projects and add it only to the Web project? Did I get right?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can remove it from all projects. then check if the problem solved.

  • User Avatar
    0
    yilmaz.132 created

    Hi,

    I tried 2 scenarios.

    1. case: When I removed it from all projects, the same problem continued. I just added this in the Web and Auth project.
    2. case: When I remove it from all projects, I get the following error.
    [web_6c4bc74a-5]: [15:42:43 WRN] Failed to refresh remote claims for user: 26af7673-d0d8-65ba-6dde-39fc9b34793c
    [web_6c4bc74a-5]: System.Net.Http.HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
    [web_6c4bc74a-5]: at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
    [web_6c4bc74a-5]: at Volo.Abp.AspNetCore.Mvc.Client.RemoteDynamicClaimsPrincipalContributorCache.RefreshAsync(Guid userId, Nullable`1 tenantId)
    [web_6c4bc74a-5]: at Volo.Abp.Security.Claims.RemoteDynamicClaimsPrincipalContributorCacheBase`1.GetAsync(Guid userId, Nullable`1 tenantId)
    [web_6c4bc74a-5]: at Volo.Abp.Security.Claims.RemoteDynamicClaimsPrincipalContributorBase`2.ContributeAsync(AbpClaimsPrincipalContributorContext context)
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Have you enabled the IsDynamicClaimsEnabled? you can set it to default(false) or remove the configure code.

    context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
    {
        options.IsDynamicClaimsEnabled = true;
    });
    

    Have you tested this case in a new microservice template project?

  • User Avatar
    0
    yilmaz.132 created

    It didn't work. The new solution is created via OpenIddict and everything works smoothly there. But our application uses IdentityServer4.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share your project source code? I need to check it on my local. liming.ma@volosoft.com

  • User Avatar
    0
    yilmaz.132 created

    Hi, I sent the project source code to your e-mail address.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Got it. Can you also share some steps? Thanks

  • User Avatar
    0
    yilmaz.132 created

    Hi,

    You can perform database migrations with the DbMigrator project and then run the project via tye. You will see the errors I mentioned in Identit Management and Identity Server Management in the Administration menu.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    public override void PreConfigureServices(ServiceConfigurationContext context)

    {
    
        context.Services.PreConfigure<AbpIdentityServerBuilderOptions>(options =>
 
        {
       
            options.UpdateAbpClaimTypes = false;
  
        });

    }
    
    

  • User Avatar
    0
    yilmaz.132 created

    Hi,

    Thank you very much. It worked when I added the code. What is the purpose of doing this?

    Other services do not have this configuration, but it still works.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    The IdentityServerHttpApiHostModule depends on the IdentityServerDomainModule and will change the claim types. We need to disable this behavior.

    The other microservices don't need to change.

    https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerBuilderExtensions.cs#L47-L53

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11