Search code examples
c#asp.net-coreidentityserver4asp.net-core-identity

remote certificate is invalid according to the validation procedure (Identity server Hosted in azure)


I tried a lot and now putting it here .. so I have an app service in which API Identity server and UI(Blazor) is hosted in different folders inside the same app service now i generated the rsa signing cert from [https://damienbod.com/2020/02/10/create-certificates-for-identityserver4-signing-using-net-core/](this blog post) now everything works fine on development even when i set hosted identity server as provider and localhost(UI and Web API) even then its working but when i try to access the hosted API its throwing error (in log) and i am getting 401 enter image description here

please any helps would be appreciated

also

my identity server startup looks like this

public void ConfigureServices(IServiceCollection services)
    {
        var settings = config.GetSection("AppSettings").Get<AppSettings>();
        X509Certificate2 rsaCertificate = null;
        if (env.IsDevelopment())
        {
            rsaCertificate = new X509Certificate2(
            Path.Combine(env.WebRootPath, "cert/rsaCert.pfx"), "password");
        }
        else
        {
            using (X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
            {
                certStore.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certCollection = certStore.Certificates.Find(
                    X509FindType.FindByThumbprint,
                    settings.CertificateDetails.CertificateThumbPrint,
                    false);
                // Get the first cert with the thumbprint
                if (certCollection.Count > 0)
                {
                    rsaCertificate = certCollection[0];
                }
            }
        }
        var connectionString = config.GetConnectionString("DefaultConnection");
        services.AddOidcStateDataFormatterCache();
        services.AddDbContext<SeatingDBContext>(x =>
        {
            x.UseSqlServer(connectionString);
        });

        services.AddIdentity<ApplicationUser, ApplicationRole>(x =>
        {
            x.Password.RequiredLength = 4;
            x.Password.RequireDigit = false;
            x.Password.RequireNonAlphanumeric = false;
            x.Password.RequireUppercase = false;
        }).AddEntityFrameworkStores<SeatingDBContext>().
     AddDefaultTokenProviders();

        services.ConfigureApplicationCookie(x =>
        {
            x.Cookie.Name = "IdentityServer.Cookie";
            x.LoginPath = "/Auth/Login";
        });

        var assembly = typeof(Startup).Assembly.GetName().Name;
        services.AddIdentityServer(x =>
        {
            x.Events.RaiseErrorEvents = true;
            x.Events.RaiseFailureEvents = true;
            x.Events.RaiseSuccessEvents = true;
            x.Events.RaiseInformationEvents = true;
        }).AddAspNetIdentity<ApplicationUser>()
  .AddInMemoryIdentityResources(Configuration.GetIdentityResources())
  .AddInMemoryApiScopes(Configuration.GetApiScopes())
   .AddInMemoryApiResources(Configuration.GetApis())
   .AddInMemoryClients(Configuration.GetClients(settings.ClientApps))
   .AddSigningCredential(rsaCertificate);
// .AddValidationKey(rsaCertificate);

        services.AddScoped(typeof(IRepository<,>), typeof(Repository<,>));

        services.AddTransient<IUserSyncService, UserSyncService>();

        services.AddControllersWithViews();
    }

and my web API looks like this

public void ConfigureServices(IServiceCollection services)
    {
        var connectionString = Configuration.GetConnectionString("DefaultConnection");
        var settings = Configuration.GetSection("AppSettings").Get<AppSettings>();
        services.AddControllers();
        services.AddDbContext<SeatingDBContext>(x => x.UseSqlServer(connectionString));
        services.AddScoped(typeof(IRepository<,>), typeof(Repository<,>));
        services.AddAutoMapper(typeof(Startup));
        services.AddScoped<IEmailService, EmailService>();
        services.AddSingleton<IEmailConfiguration>(settings.EmailConfiguration);
        services.AddScoped<MailSender>();
        services.AddControllers();
        services.AddIdentityForWebApi<ApplicationUser, ApplicationRole>(x =>
        {
            x.Password.RequiredLength = 4;
            x.Password.RequireDigit = false;
            x.Password.RequireNonAlphanumeric = false;
            x.Password.RequireUppercase = false;
        }).AddEntityFrameworkStores<SeatingDBContext>();
         
        services.AddAuthentication(defaultScheme:"Bearer")
        .AddIdentityServerAuthentication("Bearer", config =>
        {
            config.Authority = settings.ODICSettings.Authority;
            config.ApiName = settings.ODICSettings.Audience;  
        });
        services.AddAuthorization(options =>
        {
            options.AddPolicy("ApiScope", policy =>
            {
                policy.RequireAuthenticatedUser();
                foreach (string scope in settings.ODICSettings.scope)
                    policy.RequireClaim("scope", scope);
            });
        });
    }

Solution

  • You can not use the signing certificate as a HTTPS web certificate. The signing cert is only used when IdentityServer signs the JWT tokens.

    You need to get a real certificate from a trusted provider (like Lets Encrypt) and install it separately as a TLS/HTTPS certificate.

    Signing certs and TLS/HTTPS certificates are separate things that both needs to be configured properly.