How to split an IdentityServer4 MVC application into front-end UI/API and back-end API for secure hosting in DMZ?

649 Views Asked by At

My customer insists that IdentityServer4 should not be hosted entirely in DMZ for security reasons, especially considering that it has direct access to the database server.

From IdentityServer4 documentation and some other posts, it seems it should be possible to host MVC login pages in DMZ and leave IdentityServer4 API behind a firewall. If I understand correctly, I can achieve this using LoginUrl, LogoutUrl, ConsentUrl, ErrorUrl, DeviceVerificationUrl settings.

However, I'm not sure about the OpenID API. My SPA applications will need not only the login pages but also access to OpenID endpoints (connect/authorize, connect/userinfo, connect/checksession .well-known/openid-configuration).

How do I expose those IdentityServer4 endpoints in DMZ securely?

Currently I have no idea how those OpenID endpoints are created by IdentityServer4. In my app startup code, I just call AddIdentityServer and UseIdentityServer, and it does it's magic, registering the endpoints with my MVC app and then processing all the auth logic somewhere deep inside IdentityServer4.

Obviously, if I want to separate IdentityServer4 backend, I should call AddIdentityServer and UseIdentityServer in my backend API web service code, right? I can't use these method calls in my front-end website in DMZ because then IdentityServer4 will attempt to connect to the database for OpenID data, but the database is behind the firewall and unavailable directly from the DMZ.

I have the following typical code for IdentityServer4 initialization:

services.AddIdentityServer(
            options =>
            {
                ...
            })
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = b => b.UseSqlServer(Configuration.GetConnectionString("IdsvConnection"));
   ...
            })
            // this adds the operational data from DB (codes, tokens, consents)
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = b => b.UseSqlServer(Configuration.GetConnectionString("IdsvConnection"));
   ...
            })
            .AddAspNetIdentity<ApplicationUser>();

But if I leave this code in front-end, IdentityServer4 will not work. Is there some way to configure some other kind of operational and configuration store database access through backend API?

My current IdentityServer4 infrastructure looks like this:

SPA APP, 
mobile apps
     |
     |
MVC app 
with login pages 
and IdentityServer4 OpenID endpoint
     |
     |
SQL server 
with IdentityServer4 config 
and operational stores

but I need it like this:

SPA APP, 
mobile apps
     |
     |
--- DMZ ---
MVC app 
with login pages 
and IdentityServer4 OpenID endpoint
     |
     |
--- firewall ---
API web service                                
     |
     |
SQL server 
with IdentityServer4 config 
and operational stores
1

There are 1 best solutions below

0
Gary Archer On

A common requirement actually and not about coding. It is about ensuring that if DMZ is compromised the other layers are not. Standard solution is to use a reverse proxy in front of the Authorization Server (IdentityServer in your case). It ensures that UIs can still reach OAuth endpoints - but that if the DMZ infra is compromised the attacker cannot get their hands on the actual Authorixation Server and its database connections.