Configuration
The system is configured by changing configuration files in the file system and/or during installation, using a shared parameters file for the installation script.
Each service has its own set of configuration files, and the web client reads its configuration from a config file in the web-site.
The main entries in the configuration files are being automatically populated from installation parameters through the installation script, but you may tweak the installation by editing the files yourself.
You may also need to change the configuration files manually if your environment is changing, i.e. server names.
Settings that are omitted from the configuration files are inheriting the default value if available as described below.
The following configuration file examples origins from our cloud deployment and pictures a setup with:
- An SSL star-certificate for *.plassdata.net
- All services deployed to the same server
- Database service is Microsoft SQL Express running an ‘SQLEXPRESS’ instance
- Main hostname: https://dvi6test.plassdata.net
- Host is Windows Server 2016 with default settings, using drive C: for everything
Angular Client
appconfig.json
The file is located in the [INSTALL_FOLDER]\kmd-dvi\assets\config\ folder.
Note that the appconfig.json exists for every language installed. In the default installation there is the following language folders in the [INSTALL_FOLDER]\kmd-dvi\ folder: “ar-AE, de-AT, de-CH, de-DE, en-GB, en-US, es-ES, fr-CA, fr-CH, he-IL and it-CH”.
Each folder contains the appconfig.json file in the folder [INSTALL_FOLDER]\kmd-dvi\[LANGUAGE]\assets\config\
Example [INSTALL_FOLDER]\kmd-dvi\assets\config\appconfig.json:
{
"apiServer": {
"baseUrl": "https://api-dvi6test.plassdata.net",
"jwtWhitelistedDomains": "api-dvi6test.plassdata.net;dvi6test.plassdata.net"
},
"idsServer": {
"baseUrl": "https://ids-dvi6test.plassdata.net"
},
"auth": {
"clearHashAfterLogin": false,
"requireHttps": true,
"sessionChecksEnabled": true,
"showDebugInformation": false,
"strictDiscoveryDocumentValidation": true,
"timeoutFactor": 0.25
},
"ui": {
"showMapUrlTemplate": "https://www.google.com/maps/place/${dmslat}+${dmslon}/@${lat},${lon},14z",
"skin": {...},
"customMenuItems": [...],
"dateCenturyCutoff": "+5"
},
"env": {
"name": "Prod"
},
"isConfig": true
}
Option | Default | Usage |
---|---|---|
“apiServer”: { “baseUrl”: “URL“ } |
[must be specified] | Endpoint-URL of the API server. Keep in sync with *1 |
“apiServer”: { “jwtWhitelistedDomains”: “list-of-domain;domain;domain… “ } |
[must be specified] | Domain-names of accepted token origins. Typically the domain part of the API endpoint and the Angular client file endpoint |
“idsServer”: { “baseUrl”: “URL“ } |
[must be specified] | Endpoint-URL of the Identity server. Keep in sync with *2 |
“auth”: | optional section | This whole auth section is optional, and only relevant settings from it should be included if a change is necessary |
“auth”: { “adfsResourceId”: “URL“ } |
optional value | Set according to the additional documentation when adfsType > 0 |
“auth”: { “adfsType”: 0 } |
0 | Type of authentication/authorization. 0 is the included OIDC server. Other values according to the documentation of separate licensed alternatives i.e. Microsoft ADFS Integration Module |
“auth”: { “clearHashAfterLogin”: false } |
false | Defines whether to clear the hash fragment after logging in |
“auth”: { “discoveryDocumentURI”: “URI“ } |
optional value | Set according to the additional documentation when adfsType > 0 |
“auth”: { “idleLogoutTimeBeforeWarn”: 120 } |
0 | Timeout in seconds of mouse or keyboard inactivity before the Inactivity Warning dialog is displayed. 0 never logouts on inactivity |
“auth”: { “idleLogoutWarnTime”: 15 } |
15 | Timeout in seconds where the Inactivity Warning dialog is displayed before the user is automatically logged out if no action is taken. This number is emitted in 10 steps |
“auth”: { “requireHttps”: true } |
“remoteOnly” | Defines whether https is required. Default is “remoteOnly” which only allows http for localhost, while every other domains need to be used with https |
“auth”: { “scope”: “text“ } |
optional value | Set according to the additional documentation when adfsType > 0 |
“auth”: { “sessionChecksEnabled”: true } |
true | If true, the lib will try to check whether the user is still logged in on a regular basis as described in http://openid.net/specs/openid-connect-session-1_0.html#ChangeNotification |
“auth”: { “showDebugInformation”: false } |
false | Defines whether additional debug information should be shown at the console. Note that in certain browsers the verbosity of the console needs to be explicitly set to include Debug level messages |
“auth”: { “silentRefreshTimeout”: 30 } |
30 | Timeout in seconds for automatic token refresh |
“auth”: { “skipIssuerCheck”: false } |
false | Set according to the additional documentation when adfsType > 0 |
“auth”: { “strictDiscoveryDocumentValidation”: true } |
true | Defines whether every url provided by the discovery document has to start with the issuer’s url |
“auth”: { “timeoutFactor”: 0.75 } |
0.75 | Defines when the token_timeout event should be raised. If you set this to the default value 0.75, the event is triggered after 75% of the token’s life time |
“ui”: | optional section | This whole ui section is optional, and only relevant settings from it should be included if a change is necessary. See separate article |
“ui”: { “showMapUrlTemplate”: “…” } |
optional value (MPUB) | See separate article |
“ui”: { “skin”: {…} } |
optional section | See separate article |
“ui”: { “customMenuItems”: […] } |
optional section | See separate article |
“ui”: { “dateCenturyCutoff”: “+year-offset” } |
+5 | When entering dates, a no- or two-digit year may be typed, and year is converted to 4 digits as - if today is ??/??/ccYY: If typed dd/mm then formatted as dd/mm/ccYY, if typed dd/mm/?? where ?? is between 0 and (YY+dateCenturyCutoff) then formatted as dd/mm/cc??, else formatted as dd/mm/(cc-1)??, i.e. 15/5 => 15/05/2021, 15/5/12 => 15/05/2012, 15/5/22 => 15/05/2022, 15/5/30 => 15/05/1930. If you omit the +, year-offset is used as an absolute value |
“ui”: { “dateUseMaskBehavior”: true } |
false | Specifies whether to control user input using a mask created based on the displayFormat |
“ui”: { “dateShowClearButton”: false } |
true | Specifies whether to display the Clear button in the UI component |
“ui”: { “fallbackLocale”: “da-DK” } |
“en-GB” | The locale to use if not specifically set or selected by user |
“ui”: { “maxAttachmentBytesUploadSize”: 20000000 } |
10000000 | Specifies the maximum upload file size, in bytes |
“ui”: { “attachmentAllowedFileTypes”: [ “.jpg”, “.pdf” ] } |
any file type | Specifies the allowed upload file extensions. The FileManager UI cannot upload a file and displays an error message when the file’s extension is not allowed. Remember to include the values in array indicators [ ] separated by comma and prefix the extension with a dot . |
“ui”: { “useAskExplicitAccessLanding”: true } |
false | See separate article |
“ui”: { “allowAttachmentsBeforeGridSave”: false } |
true | Defines if you’re able to add B- and C- columns to gridrows (Field 300,305, etc.) before saving the row. If the setting is omitted, the value is set to true |
“env”: { “name”: “Prod” } |
[must be specified] | “Name” always set to “Prod” |
“isConfig”: true | [must be specified] | Always set to true |
web.config (Windows, IIS)
[INSTALL_FOLDER]\kmd-dvi\web.config:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect all requests" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
web.config has a static content that instructs Internet Information Services to redirect all requests that is NOT for a specific file or folder to the root of the client where it is picked up and routed by Angular javascript.
plassidweb.conf (Linux, nginx - example naming)
/etc/nginx/conf.d/plassidweb.conf:
server {
listen 0.0.0.0:80;
server_name web.dvitraefik.local;
large_client_header_buffers 4 16k;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
}
}
plassidweb.conf instructs nginx to redirect all requests that is NOT for a specific file or folder to the root of the client where it is picked up and routed by Angular javascript. The server_name entry is necessary to point to the root path of the DVI client web site if other sites are running at the same nginx web server. Other changes may be necessary to adapt the file to your specific environment.
API Data Server
Example [INSTALL_FOLDER]\api\appsettings.json:
{
"CORS": {
"AllowedHosts": "https://dvi6test.plassdata.net;https://api-dvi6test.plassdata.net;https://ids-dvi6test.plassdata.net"
},
"connectionStrings:defaultConnection": "",
"connectionStrings:tempReportDVIConnection": "XpoProvider=MSSqlServer;Persist Security Info=true",
"deployment:enableSwagger": false,
"deployment:platform": "windowsvm",
"server:apiPublicEndpoint": "https://api-dvi6test.plassdata.net",
"server:apiLocalEndpoint": "https://api-dvi6test.plassdata.net",
"server:idsPublicEndpoint": "https://ids-dvi6test.plassdata.net",
"server:idsLocalEndpoint": "https://ids-dvi6test.plassdata.net",
"sql:api2sql:dataSource": ".\\SQLEXPRESS",
"sql:ids2sql:dataSource": ".\\SQLEXPRESS",
"sql:job2sql:dataSource": ".\\SQLEXPRESS",
"token:audience": "vic_api_res",
"token:nameClaimType": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
}
Common settings
Common settings can/must be put in both the API Data Server and IdentityServer configuration files
Option | Default | Usage |
---|---|---|
“CORS”: { “AllowedHosts”: “list-of-host;host;host… “ } |
[must be specified] | List of all host URLs that may originate HTTP requests, separated by ; |
connectionStrings:defaultConnection | empty | Template connectionstring where datasource, catalog and authentication options are added according to settings. Enables you to specify further SQL connections settings such as encryption or certificates |
dataPath:licenseFolderSubPath | Data/LicenseFiles | Server harddisk subfolder where the license file(s) is stored |
deployment:allowHttp | false | set to ‘true’ to allow endpoints to be bound to a port not requiring HTTPS, see important note |
deployment:enableForwardedHeaders | false | set to ‘true’ to use forwarded headers, supported are XForwardedFor, XForwardedProto and XForwardedHost see Mozilla |
deployment:enableSerilogRequestLogging | false | set to ‘true’ to log all incoming http requests to the service |
deployment:enableSwagger | false | set to true to enable swagger endpoint for API definition readout |
deployment:enableHangfire | true | set to false to disable Hangfire Jobserver on this IIS |
deployment:platform | windowsvm | reserved for future use |
server:idsPublicEndpoint | [must be specified] | Binding of Plass.Id.Identity service on the public boundary server, i.e. https://ids-dvi6test.plassdata.net ids-dvi6test is used instead of ids.dvi6test as https * certificates does only cover one level above certificate root. You may choose any binding supported by your certificates. Keep in sync with *2 |
server:idsLocalEndpoint | [must be specified] | Binding of Plass.Id.Identity service on the local server. If you are not using a boundary server (proxy, firewall etc), you must specify it identical to the above public endpoint |
sql:[xxx]2sql:authorization | integrated | [xxx] = ‘api’, ‘ids’ or ‘job’ Authentication method from service to SQL Server. Change to SQL to use configuration-stored username and password (not recommended on Windows) |
sql:[xxx]2sql:encrypt | true | change to false to use unencrypted traffic between service and SQL Server[xxx] = ‘api’, ‘ids’ or ‘job’ |
sql:[xxx]2sql:trustServerCertificate | true | change to false to enforce full check of SQL Server certificates used for encryption (recommended if encrypt is true and the SQL server is shared/external)[xxx] = ‘api’, ‘ids’ or ‘job’ |
sql:[xxx]2sql:dataSource | [must be specified] | SQL Server Hostname, i.e. .\\SQLEXPRESS for a local SQL Express server.[xxx] = ‘api’, ‘ids’ or ‘job’ |
sql:[xxx]2sql:password | [must be specified if SQL authorization] |
SQL Server Authorization User Password if SQL specified in sql:[xxx]2sql:authorization[xxx] = ‘api’, ‘ids’ or ‘job’ |
sql:[xxx]2sql:user | [must be specified if SQL authorization] |
SQL Server Authorization User Name if SQL specified in sql:[xxx]2sql:authorization[xxx] = ‘api’, ‘ids’ or ‘job’ |
sql:ids2sql:catalog | PLASS_ID_IDENTITY | Name of database used by Plass.Id.Identity.exe, IdentityServer4 Service |
5 | ||
token:nameClaimType | Must be included in config file as-is |
Note on HTTPS versus HTTP
Using HTTPS is a very important security aspect, and you should only allow HTTP if you have other security measures in place, i.e. perimeter HTTPS proxies, for the communication between clients and your server.
Enforcing end-to-end HTTPS security is being increasingly required by all kinds of components that takes part in the information exchange, and KMD is not able to ensure that the use of HTTP only, even only between our internal servers, will remain a possible option, and your network administrators should be aware of this.
If you are offloading SSL on boundary servers, you should configure these to forward the external headers and enable deployment:enableForwardedHeaders and deployment:allowHttp. You must also configure all xxxLocalEndpoint to reflect the differing internal protocol and urls on the inside of the boundary server.
Already now, you will not be able to authenticate and test the sites using only HTTP if using Chromium based browsers, as their cookie protection does not allow cookies from different sites (id-server versus api-server) to be stored when not using HTTPS. This behavior may propagate to other browsers over time.
API Service specific settings
Option | Default | Usage |
---|---|---|
dataPath:advancedSearchDatamodelSubPath | Data/Datamodels | Server harddisk subfolder where datamodels for the advanced search are stored |
dataPath:afisStorageFolderSubPath | Data/AfisStorage | Server harddisk subfolder where NIST files for AFIS are stored (reserved for future) |
dataPath:attachmentStorageFolderSubPath | Data/AttachmentStorage | Server harddisk subfolder where file attachments are stored (reserved for future, where you may select to store attachments separate from the database tables) |
dataPath:dashboardDefinitionsFolderSubPath | Data/Dashboards | Server harddisk subfolder where Dashboard Definition Files are stored |
dataPath:reportDefinitionsFolderSubPath | Data/Reports | Server harddisk subfolder where Report Definition Files are stored |
dataPath:licenseFolderSubPath | Data/LicenseFiles | Server harddisk subfolder where the license file(s) is stored |
dataPath:workFileFolderSubPath | Data/WorkFiles | Server harddisk temporary workfiles are stored i.e. during import, export and some report generation |
server:apiPublicEndpoint | [must be specified] | Binding of Plass.Id.Data.Api service on the public boundary server, i.e. https://api-dvi6test.plassdata.net api-dvi6test is used instead of api.dvi6test as https * certificates does only cover one level above certificate root. You may choose any binding supported by your certificates. Keep in sync with *2 |
server:apiLocalEndpoint | [must be specified] | Binding of Plass.Id.Data.Api service on the local server. If you are not using a boundary server (proxy, firewall etc), you must specify it identical to the above public endpoint |
server:idsAuthorizationPath | /connect/authorize | reserved for future use | |
server:utcOffset | 0.0 | Sets the local UTC offset. Used for conversion of certain dates from V5 to V6 | |
server:scheduleRecurringDentalMatch | ”* * * * * “ | Uses a CRON expression to schedule when to run a recurring dental match | |
sql:api2sql:catalog | PLASS_ID_COMMON | Name of database used by Plass.Id.Data.Api.exe, API Data service | |
sql:job2sql:catalog | PLASS_ID_JOBS | Name of database used by Plass.Id.Data.Api.exe, Jobs Scheduler Service | |
deployment:enableDeveloperExceptions | false | Set to true in case problem solving needs more debug data. Use only in coordination with KMD | |
deployment:enableForwardedHeadersLogging | false | Log all incoming HTTP headers if also DEBUG log level is set | |
endpoints:signalr:match | /signalr/match | Hub endpoint for matching-status messages (not yet configurable client-side) | |
endpoints:signalr:message | /signalr/message | Hub endpoint for inter-process or personal messages (not yet configurable client-side) | |
endpoints:signalr:job | /signalr/job | Hub endpoint for job-server progress messages (not yet configurable client-side) | |
search:limits:advancedRecords | 10000 | Maximum number of Advanced Search matches to return to client | |
search:limits:fulltextRecords | 10000 | Maximum number of Fulltext Search matches to return to client | |
security:allowViewNamesAcrossAgencies | false | Removes restrictions on names across agencies on MPUB files | |
token:audience | vic_api_res | Must be included in config file as-is | |
upload:maxByteSize | 409600000 | Maximum upload filesize in bytes. Regarding attachments and import files |
web.config (Windows, IIS)
[INSTALL_FOLDER]\api\web.config:
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath=".\Plass.Id.Data.Api.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess"/>
<security>
<requestFiltering>
<requestLimits maxQueryString="4096"/>
</requestFiltering>
</security>
</system.webServer>
</location>
</configuration>
Besides the setting for maxQueryString, the content of the web.config is standard and shouldn’t be altered.
The default value of maxQueryString (if it is not assigned) is 1024, but the search routines in DVI V6 requires more space allocated for the parameters, hence the value of 4096.
Identity Server
Example [INSTALL_FOLDER]\ids\appsettings.json:
{
"CORS": {
"AllowedHosts": "https://dvi6test.plassdata.net;https://api-dvi6test.plassdata.net;https://ids-dvi6test.plassdata.net"
},
"authentication:passwordRuleHistoryLimit": 3,
"authentication:passwordRulesEnforcePasswordExpire": true,
"authentication:passwordRulesInactivityLockoutExpireDays": 30,
"authentication:passwordRulesMaxPasswordChangesPerDay": 2,
"authentication:passwordRulesPasswordExpireDays": 90,
"connectionStrings:DefaultConnection": "",
"deployment:enableSwagger": false,
"deployment:platform": "windowsvm",
"lockout:defaultLockoutTimeSpan": {
"hours": 0,
"minutes": 30,
"seconds": 0
},
"lockout:maxFailedAccessAttempts": 3,
"password:requireDigit": true,
"password:requireLowercase": true,
"password:requireNonAlphanumeric": true,
"password:requireUppercase": true,
"password:requiredLength": 10,
"password:requiredUniqueChars": 0,
"server:apiPublicEndpoint": "https://api-dvi6test.plassdata.net",
"server:apiLocalEndpoint": "https://api-dvi6test.plassdata.net",
"server:idsPublicEndpoint": "https://ids-dvi6test.plassdata.net",
"server:idsLocalEndpoint": "https://ids-dvi6test.plassdata.net",
"sql:ids2sql:dataSource": ".\\SQLEXPRESS"
"token:audience": "ids_api_res",
"token:nameClaimType": "email"
}
Authentication Policies
Option | Default | Usage | |
---|---|---|---|
deployment:enableDeveloperExceptions | false | Set to true in case problem solving needs more debug data. Use only in coordination with KMD | |
token:accessTokenLifetime | 1800 | Access token lifetime in seconds | |
token:identityTokenLifetime | 120 | Identity token lifetime in seconds | |
token:deviceTokenLifetime | 36000 | Device token lifetime in seconds | |
authentication:passwordRuleHistoryLimit | 0 | How many old passwords should be refused for reuse | |
authentication:passwordRulesEnforcePasswordExpire | false | Whether password change should be required on expiry | |
authentication:passwordRulesInactivityLockoutExpireDays | 0 | Whether a user is permanently locked out after x days of inactivity | |
authentication:passwordRulesMaxPasswordChangesPerDay | 0 | How often a password may be changed per day, 0 = no limit | |
authentication:passwordRulesPasswordExpireDays | 0 | Password lifetime in days, 0 = indefinite | |
lockout:defaultLockoutTimeSpan | { “hours”: 0, “minutes”: 5, “seconds”: 0 } | Timespan a user is locked out for when a lockout occurs | |
lockout:maxFailedAccessAttempts | 5 | Number of failed access attempts allowed before a user is locked out | |
password:requireDigit | true | ||
password:requireLowercase | true | ||
password:requireNonAlphanumeric | true | ||
password:requireUppercase | true | ||
password:requiredLength | 10 | ||
password:requiredUniqueChars | 0 | Minimum number of different characters in password |
Other settings like the Common Settings plus:
Option | Default | Usage |
---|---|---|
server:webPublicEndpoint | [must be specified] | Binding of Angular client file URL path on the public boundary server, i.e. https://dvi6test.plassdata.net , used to validate claimed callback-path from IdentityServer to Angular client. |
server:webLocalEndpoint | [must be specified] | Binding of Angular client file URL path on the local server. If you are not using a boundary server (proxy, firewall etc), you must specify it identical to the above public endpoint |
token:audience | ids_api_res | Must be included in config file as-is |