Add Configuration settings for CORS whitelist (#29)

* Add Configuration settings for CORS whitelist

* Check for null values generated in deserializing incorrect CORS whitelist

* Hard code CORS whitelist

* Remove reference to environment variable PCS_DEVICESIMULATION_CORS_WHITELIST
This commit is contained in:
Xiangzhi Sheng 2017-08-08 10:15:07 +08:00 коммит произвёл GitHub
Родитель ec020b9a1c
Коммит d93c5e5013
4 изменённых файлов: 96 добавлений и 0 удалений

Просмотреть файл

@ -14,6 +14,9 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime
/// <summary>Web service listening port</summary>
int Port { get; }
/// <summary>CORS whitelist, in form { 'origins': [], 'methods': [], 'headers': [] }</summary>
string CorsWhitelist { get; }
/// <summary>Service layer configuration</summary>
IServicesConfig ServicesConfig { get; }
}
@ -25,6 +28,7 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime
private const string PortKey = ApplicationKey + "webservice_port";
private const string DeviceTypesFolderKey = ApplicationKey + "device_types_folder";
private const string DeviceTypesScriptsFolderKey = ApplicationKey + "device_types_scripts_folder";
private const string CorsWhitelistKey = ApplicationKey + "cors_whitelist";
private const string IoTHubManagerKey = "iothubmanager:";
private const string IoTHubManagerApiUrlKey = IoTHubManagerKey + "webservice_url";
@ -33,12 +37,16 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime
/// <summary>Web service listening port</summary>
public int Port { get; }
/// <summary>CORS whitelist, in form { 'origins': [], 'methods': [], 'headers': [] }</summary>
public string CorsWhitelist { get; }
/// <summary>Service layer configuration</summary>
public IServicesConfig ServicesConfig { get; }
public Config(IConfigData configData)
{
this.Port = configData.GetInt(PortKey);
this.CorsWhitelist = configData.GetString(CorsWhitelistKey);
this.ServicesConfig = new ServicesConfig
{

Просмотреть файл

@ -0,0 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime
{
class CorsWhitelistModel
{
public string[] Origins { get; set; }
public string[] Methods { get; set; }
public string[] Headers { get; set; }
}
}

Просмотреть файл

@ -1,14 +1,17 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Linq;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.Runtime;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService
{
@ -34,6 +37,9 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService
// Configure method below.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add CORS service
services.AddCors();
// Add controllers as services so they'll be resolved.
services.AddMvc().AddControllersAsServices();
@ -66,11 +72,80 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService
{
loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
app.UseCors(this.BuildCorsPolicy);
app.UseMvc();
// If you want to dispose of resources that have been resolved in the
// application container, register for the "ApplicationStopped" event.
appLifetime.ApplicationStopped.Register(() => this.ApplicationContainer.Dispose());
}
private void BuildCorsPolicy(CorsPolicyBuilder builder)
{
var config = this.ApplicationContainer.Resolve<IConfig>();
var logger = this.ApplicationContainer.Resolve<Services.Diagnostics.ILogger>();
CorsWhitelistModel model;
try
{
model = JsonConvert.DeserializeObject<CorsWhitelistModel>(config.CorsWhitelist);
if (model == null)
{
logger.Info("Invalid CORS whitelist. Ignored", () => new { config.CorsWhitelist });
return;
}
}
catch (Exception ex)
{
logger.Info("Invalid CORS whitelist. Ignored", () => new { config.CorsWhitelist, ex.Message });
return;
}
if (model.Origins == null)
{
logger.Info("No setting for CORS origin policy was found, ignore", () => { });
}
else if (model.Origins.Contains("*"))
{
logger.Info("CORS policy allowed any origin", () => { });
builder.AllowAnyOrigin();
}
else
{
logger.Info("Add specified origins to CORS policy", () => new { model.Origins });
builder.WithOrigins(model.Origins);
}
if (model.Origins == null)
{
logger.Info("No setting for CORS method policy was found, ignore", () => { });
}
else if (model.Methods.Contains("*"))
{
logger.Info("CORS policy allowed any method", () => { });
builder.AllowAnyMethod();
}
else
{
logger.Info("Add specified methods to CORS policy", () => new { model.Methods });
builder.WithMethods(model.Methods);
}
if (model.Origins == null)
{
logger.Info("No setting for CORS header policy was found, ignore", () => { });
}
else if (model.Headers.Contains("*"))
{
logger.Info("CORS policy allowed any header", () => { });
builder.AllowAnyHeader();
}
else
{
logger.Info("Add specified headers to CORS policy", () => new { model.Headers });
builder.WithHeaders(model.Headers);
}
}
}
}

Просмотреть файл

@ -1,5 +1,7 @@
[devicesimulation]
webservice_port = ${PCS_DEVICESIMULATION_WEBSERVICE_PORT}
cors_whitelist = "{ 'origins': ['*'], 'methods': ['*'], 'headers': ['*'] }"
# Note: in linux containers, the `data` folder is a symlink to /app/data
# which can be mounted to inject custom device types and scripts.
device_types_folder = ./data/DeviceTypes/