Skip to content

User Interfaces#

All User Interfaces are served by a web server, Traefik or Microsoft IIS for containerized and traditional installations, respectively. In both cases, all the resources are secured through a middleware that ensures that only authenticated users have access to the Critical Manufacturing UI assets.

For Traefik, a Forward Auth middleware is configured for the UI routes, ensuring the traffic is only sent to the final endpoint after validating if the user is authenticated and authorized. Similarly, for Microsoft IIS, an IIS Module acts as a middleware with the same purpose.

Forward Auth#

When an MES Customer Environment is deployed through the Critical Manufacturing DevOps Center, an IngressRoute for the Critical Manufacturing UI container is created, with a set of Middlewares and Service endpoints. For every asset, except for the manifest, the traffic will first go through the Forward Auth middleware, as you can see in the YAML snippets below:

Route#

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  labels:
    ...
  name: ui
  namespace: mes
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: PathPrefix(`/`) && !PathPrefix(`/apps/`)
      middlewares:
        - name: ui-headers
          namespace: mes
        - name: ui-auth
          namespace: mes
      services:
        - kind: Service
          name: ui
          namespace: mes
          port: 8080
    - kind: Rule
      match: PathPrefix(`/manifest.json`) && !PathPrefix(`/apps/`)
      services:
        - kind: Service
          name: ui
          namespace: mes
          port: 8080

Middleware#

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  labels:
    ...
  name: ui-auth
  namespace: mes
spec:
  forwardAuth:
    address: 'http://traefik-forwardauth:8080/api/auth/validate'
    authResponseHeaders:
      - X-Forwarded-User
    trustForwardHeader: true

The middleware ensures that the Traefik will first forward the request to the Forward Auth container, which will validate the authentication and authorization together with the Security Portal, returning a response with the validation outcome. If it succeeds, the X-Forwarded-User response header is populated with the user from the authentication details and the Traefik will then forward the traffic to the initial URL.

However, if the validation fails, the user is redirected to the Security Portal to login into the system.

Web.config#

While the Security Portal and the Forward Auth are mandatory and always enabled for containerized installations, traditional installations may be installed without the Security Portal enabled. To setup your User Interface with it, just add this to your Web.config.

All URLs starting with /iis/ should not be handled by URL Rewrite, otherwise this module will not work. Please add <add input="{REQUEST_URI}" matchType="Pattern" pattern="^/iis(/.*)?$" ignoreCase="true" negate="true"/> to your URL Rewrite match expression.

<configuration>
    <connectionStrings>
        <!-- IIS Session Storage -->
        <add name="SessionDatabase" connectionString="Data Source={DatabaseServer}\{Instance};Initial Catalog={DatabaseName};User ID={User};Password={Password};" providerName="System.Data.SqlClient"/>
    </connectionStrings>

    <system.webServer>
        <!-- Modules order is important -->
        <modules>
            <!-- Authentication Module -->
            <add name="CmfAuth" type="Cmf.Auth.IIS.Module.AuthenticationModule, Cmf.Auth.IIS.Module"/>
            <!-- Report Authentication (optional) -->
            <add name="CmfAuthReports" type="Cmf.Auth.IIS.Module.ReportServer.ReportServerModule, Cmf.Auth.IIS.Module"/>
        </modules>
    </system.webServer>
    <appSettings>
        <add key="CmfAuth_ClientId" value="{SecurityPortal Client Id}"/>
        <add key="CmfAuth_ClientSecret" value="{Security Portal Client Secret}"/>
        <add key="CmfAuth_UserEndpoint" value="http(s)://{SecurityPortalAddress}:{SecurityPortalPort}/tenant/{tenantName}/"/>
        <add key="CmfAuth_ApiEndpoint" value="http(s)://{SecurityPortalAddress}:{SecurityPortalPort}/api/tenant/{tenantName}/"/>
        <!-- For multi-tenant support. Use <tenant> has {tenantName} placeholder -->
        <!--<add key="CmfAuth_UrlMatcher" value="^http://(?&lt;tenant&gt;[^\..]+)\.local\.com.*$" />-->
        <add key="CmfAuthReports_ReportServerBaseUrl" value="http://{ReportServer}/" />
    </appSettings>
</configuration>