microsoft/fhir-server

How to enable custom IdentityServer locally

LodewijkSioen opened this issue · 2 comments

I would like to run the Docker image locally and use a self hosted IdentityServer. I keep getting 401s with Authentication Failed. The WWW-Authenticate header contains the following information:

Bearer authorization_uri="https://localhost:7023", resource_id="api-m2m", realm="api-m2m", error="invalid_token", error_description="The issuer 'https://localhost:7023' is invalid"

My token has the following information:

{
  "alg": "RS256",
  "kid": "717BA263BF10CE3AD327817F9E3C1E11",
  "typ": "at+jwt"
}.{
  "nbf": 1707994869,
  "exp": 1707998469,
  "iss": "https://localhost:7023",
  "aud": "api-m2m",
  "client_id": "33c7aa88-e639-427a-86be-160f684aa8d7",
  "tenant": "local",
  "fhirUser": "",
  "jti": "8967E4AF94DCE9F508D5236EE1CAD53A",
  "iat": 1707994869,
  "scope": [
    "bingli.client",
    "system/Task.read"
  ]
}.[Signature]

The docker image has the following environment variables:

FhirServer__Security__Enabled: "true"
FhirServer__Security__EnableAadSmartOnFhirProxy: "false"
FhirServer__Security__Authentication__Authority: "https://localhost:7023"
FhirServer__Security__Authentication__Audience: "api-m2m"

When I set the LogLevel to Informational I get the following output in de docker logs:

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty.
   at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuerAsync(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
   at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuer(String issuer, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
   at Microsoft.IdentityModel.Tokens.InternalValidators.ValidateAfterSignatureFailed(SecurityToken securityToken, Nullable`1 notBefore, Nullable`1 expires, IEnumerable`1 audiences, TokenValidationParameters validationParameters, BaseConfiguration configuration)
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateSignature(JsonWebToken jwtToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateSignatureAndIssuerSecurityKey(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)
   at Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWSAsync(JsonWebToken jsonWebToken, TokenValidationParameters validationParameters, BaseConfiguration configuration)

I've been banging my head against the wall for a while now. What am I doing wrong, or did I misunderstand what is possible?

I just tried it by running the server from source (so no docker) and this works. It's just from inside docker that the problem pops up.

So after a day of trying stuff out and looking angrily at some source code, I figured it out. The problem is twofold:

  • localhost in a docker container is not you local PC. So when the fhir server tries to get the /.well-known/openid-configuration it cannot find it. I fixed this by moving my IdentityServer behind a dev tunnel
  • The second part was adding the UseForwardedHeaders middleware so IdentityServer correctly populates the configuration with the adress of the dev tunnel.