diff --git a/WebService/Auth/AuthMiddleware.cs b/WebService/Auth/AuthMiddleware.cs index a15445ff..22f6c1dc 100644 --- a/WebService/Auth/AuthMiddleware.cs +++ b/WebService/Auth/AuthMiddleware.cs @@ -53,6 +53,7 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth private TokenValidationParameters tokenValidationParams; private readonly bool authRequired; private bool tokenValidationInitialized; + private DateTime tokenValidationExpiration; public AuthMiddleware( // ReSharper disable once UnusedParameter.Local @@ -67,6 +68,7 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth this.log = log; this.authRequired = config.AuthRequired; this.tokenValidationInitialized = false; + this.tokenValidationExpiration = DateTime.UtcNow; // This will show in development mode, or in case auth is turned off if (!this.authRequired) @@ -83,7 +85,8 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth this.config.JwtIssuer, this.config.JwtAudience, this.config.JwtAllowedAlgos, - this.config.JwtClockSkew + this.config.JwtClockSkew, + this.config.OpenIdTimeToLive }); this.InitializeTokenValidationAsync(CancellationToken.None).Wait(); @@ -196,7 +199,8 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth private async Task InitializeTokenValidationAsync(CancellationToken token) { - if (this.tokenValidationInitialized) return true; + // If the token has been initialized and is not past expiry, return. + if (this.tokenValidationInitialized && !this.TokenValidationExpired()) return true; try { @@ -224,6 +228,7 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth }; this.tokenValidationInitialized = true; + this.tokenValidationExpiration = DateTime.UtcNow.Add(this.config.OpenIdTimeToLive); } catch (Exception e) { @@ -232,5 +237,14 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth return this.tokenValidationInitialized; } + + /// + /// Checks if the OpenId Connect token has hit the expiration time. + /// + /// true if the token has expired + private bool TokenValidationExpired() + { + return this.tokenValidationExpiration > DateTime.UtcNow; + } } } diff --git a/WebService/Auth/ClientAuthConfig.cs b/WebService/Auth/ClientAuthConfig.cs index effeb221..68259d6f 100644 --- a/WebService/Auth/ClientAuthConfig.cs +++ b/WebService/Auth/ClientAuthConfig.cs @@ -36,6 +36,12 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth // Clock skew allowed when validating tokens expiration // Default: 2 minutes TimeSpan JwtClockSkew { get; set; } + + // Time to live for the OpenId Connect validation token. + // The metadata settings will expire so the token needs to be + // periodically recreated. + // Default: 7 days + TimeSpan OpenIdTimeToLive { get; set; } } public class ClientAuthConfig : IClientAuthConfig @@ -49,5 +55,6 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Auth public string JwtIssuer { get; set; } public string JwtAudience { get; set; } public TimeSpan JwtClockSkew { get; set; } + public TimeSpan OpenIdTimeToLive { get; set; } } } diff --git a/WebService/Runtime/Config.cs b/WebService/Runtime/Config.cs index 8464205a..b9862133 100644 --- a/WebService/Runtime/Config.cs +++ b/WebService/Runtime/Config.cs @@ -92,6 +92,9 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime private const string JWT_AUDIENCE_KEY = JWT_KEY + "audience"; private const string JWT_CLOCK_SKEW_KEY = JWT_KEY + "clock_skew_seconds"; + private const string OPEN_ID_KEY = APPLICATION_KEY + "ClientAuth:OpenIdConnect:"; + private const string OPEN_ID_TTL_KEY = OPEN_ID_KEY + "timeToLiveDays"; + private const string DEPLOYMENT_KEY = APPLICATION_KEY + "Deployment:"; private const string AZURE_SUBSCRIPTION_DOMAIN = DEPLOYMENT_KEY + "azure_subscription_domain"; private const string AZURE_SUBSCRIPTION_ID = DEPLOYMENT_KEY + "azure_subscription_id"; @@ -161,6 +164,8 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime JwtAudience = configData.GetString(JWT_AUDIENCE_KEY, String.Empty), // By default the allowed clock skew is 2 minutes JwtClockSkew = TimeSpan.FromSeconds(configData.GetInt(JWT_CLOCK_SKEW_KEY, 120)), + // By default the time to live for the OpenId connect token is 7 days + OpenIdTimeToLive = TimeSpan.FromDays(configData.GetInt(OPEN_ID_TTL_KEY, 7)) }; } diff --git a/WebService/WebService.csproj b/WebService/WebService.csproj index 0156a5e3..31b46e00 100644 --- a/WebService/WebService.csproj +++ b/WebService/WebService.csproj @@ -36,7 +36,7 @@ - + diff --git a/WebService/appsettings.ini b/WebService/appsettings.ini index 75e87a53..316f826c 100644 --- a/WebService/appsettings.ini +++ b/WebService/appsettings.ini @@ -208,6 +208,11 @@ audience="${?PCS_AUTH_AUDIENCE}" # Default: 2 minutes clock_skew_seconds = 300 +[TelemetryService:ClientAuth:OpenIdConnect] +; Time to live for the OpenId Connect validation token. +; The metadata settings will expire so the token needs to be periodically recreated. +; Default: 7 days +timeToLiveDays = 7 # For more information about ASP.NET logging see # https://docs.microsoft.com/aspnet/core/fundamentals/logging diff --git a/scripts/docker/content/set_env.sh b/scripts/docker/content/set_env.sh index 98fb41de..798cb09d 100644 --- a/scripts/docker/content/set_env.sh +++ b/scripts/docker/content/set_env.sh @@ -81,10 +81,14 @@ set_env_vars() { while test ${#} -gt 0 do _key=$1 - _value=$(_get_keyvault_secret $2) - - # export in current shell - export $_key=$_value + + if [ -z "${!_key}" ]; then + _value=$(_get_keyvault_secret $2) + # export in current shell + export $_key=$_value + else + echo "Variable $_key already set." + fi shift shift