IBM Security Verify Intégration

IBM Security Verify SSO pour Tomcat utilisant IBM Application Gateway

IBM Security Verify peut être utilisé pour fournir une identité basée sur le cloud à IBM Application Gateway (IAG) en utilisant la norme OIDC. IAG est un proxy inverse léger qui fournit l'authentification et l'autorisation aux serveurs d'applications web. IAG peut également être utilisé pour appliquer des politiques d'authentification supplémentaires basées sur le chemin (telles que 2FA) lorsque nécessaire.

Connaissances supposées

Ce guide suppose que vous êtes familier avec les applications IBM Security Verify et la gestion d'un registre d'utilisateurs basé sur le cloud. Les utilisateurs doivent également être familiers avec la configuration d'IBM Application Gateway. Spécifiquement, vous devriez être capable de :

  • Créer une nouvelle application IBM Security Verify à partir du modèle IAG.
  • Configurer une source d'identité.
  • Configurer un serveur de ressources.
  • Définir la configuration SSL
    • Clé/certificat SSL pour le trafic https.
    • SSL mutuel pour les serveurs de ressources protégés.

Les utilisateurs doivent également être familiers avec la configuration d'IBM Application Gateway (IAG). Spécifiquement, vous devriez être capable de configurer une source d'identité et un serveur de ressources. Vous devez également fournir l'ICP requise pour supporter les connexions SSL entre IAG et le serveur jonctionné.

Prérequis

Pour utiliser ce guide, vous devriez avoir :

  • Un serveur Tomcat configuré pour l'authentification SSO (ce guide)
  • Un abonnement IBM Security Verify ou un compte d'essai valide

Configurer IBM Security Verify

Le guide de scénario verify peut être utilisé pour configurer un locataire IBM Security Verify pour fournir des capacités SSO à IBM Application Gateway. Une application IAG devrait être créée ou mise à jour pour supporter la nouvelle instance IAG. Cela impliquera probablement de modifier les entrées redirect_uri pour inclure le DNS/nom d'hôte que l'instance IAG protège.

Le registre d'utilisateurs devrait également être configuré maintenant (si ce n'est pas déjà fait). IBM Security Verify supporte les utilisateurs d'annuaire cloud ainsi que les sources d'identité fédérées.

Déploiement d'IBM Application Gateway

Pour configurer IAG pour transmettre les informations d'identité d'IBM Security Verify à Tomcat, les clés de configuration resource_servers et identity sont utilisées. La configuration requise pour chaque clé est détaillée ci-dessous.

Serveurs de ressources

La clé serveur de ressources est utilisée pour configurer les applications en aval qui seront protégées par IAG. Au minimum, un chemin de jonction (préfixé avec un /) et un serveur de ressources doivent être définis. L'en-tête d'identité JWT et la configuration de jeton supplémentaire sont également définies ici pour le serveur Tomcat en aval.

Le serveur d'intégration cible peut être identifié par un nom DNS ou une adresse IP, pour les environnements Kubernetes cela devrait être le service créé pour le déploiement Tomcat cible. Le certificat X509 (ou un certificat signataire) configuré pour l'authentification mutuelle (ex : iag.pem) doit être un certificat de confiance dans le magasin de clés utilisé par Tomcat.

L'émetteur configuré (iss), l'audience (aud) et le sujet (sub) pour le JWT doivent correspondre à la configuration définie dans la configuration XML du serveur Tomcat. L'ICP utilisée pour signer (et chiffrer) le JWT généré doit également être importée dans le magasin de clés utilisé par le serveur Tomcat. Tomcat ne supporte que l'utilisation de l'en-tête Authorization pour fournir les JWT et devrait être de la forme Authorization: Bearer <j.w.t>.

resource_servers:
  - path: "/tomcatsso"
    connection_type: ssl
    transparent_path: false
    sni: "demo-tomcat-server"
    mutual_auth:
      certificate_auth:
        certificate:
          - "@iag.pem"
          - "@iag.key"
    servers:
      - host: "demo-tomcat-server"
        port: 8443
        ssl:
          certificate:
            - "@integration.target.pem"
    identity_headers:
      jwt:
        hdr_name: "Authorization"
        certificate:
          - "@iag.pem"
          - "@iag.key"
        claims:
          - text: "www.ibm.com"
            name: iss
            type: string
          - attr: AZN_CRED_PRINCIPAL_NAME
            name: sub
            type: string
          - text: "demo.tomcat.server"
            name: aud
            type: string
          - attr: groups
            name: groups
            type: string

Identité

La clé identité peut être utilisée pour configurer IAG comme un RP OIDC. Vous pouvez utiliser l'application IBM Security Verify créée ici pour fournir des informations d'identité à IAG. L'exemple fourni fait également usage de types de données spéciaux qu'IAG expose pour obfusquer les informations sensibles qui peuvent être requises pour définir votre déploiement. Dans ce cas, l'id client et le secret pour l'application IBM Security Verify sont stockés dans un secret Kubernetes au lieu d'une config map ou définis dans le yaml de déploiement.

La définition oidc mappe également l'attribut preferred_username au lieu de l'attribut sub retourné dans les revendications de Verify. Ceci est fait pour retourner un attribut reconnaissable humainement comme nom de Principal disponible à l'application en aval.

identity:
  oidc:
    client_id: secret:ibm-verify-oidc-integration/client_id
    client_secret: secret:ibm-verify-oidc-integration/client_secret
    discovery_endpoint: https://your.tenant.ibmcloudsecurity.com/oidc/endpoint/default/.well-known/openid-configuration
    redirect_uri_host: ibm.security.integration.demo:30443
    mapped_identity: "{preferred_username}"
    ssl:
      certificate:
        - "@verify_tenant_ca.pem"
    response_type: code
    response_mode: query

Configuration avancée :

IAG nécessite quelques paramètres de configuration avancés supplémentaires pour fournir un JWT dans le format correct. Le format d'en-tête doit être modifié pour inclure la chaîne statique Bearer. Le nom de la strophe pour cette propriété dépend du nom de jonction vers le serveur Tomcat. Si un nom de jonction différent est utilisé, alors la clé de strophe devrait être mise à jour vers jwt:/<nom de jonction>.

    advanced:
      configuration:
        - stanza: "jwt:/tomcatsso"
          entry: "hdr-format"
          operation: set
          value: "Bearer %TOKEN%"

Authentification de second facteur (2FA) avec IBM Security Verify

Un certain nombre de politiques d'authentification supplémentaires peuvent être appliquées aux ressources protégées pour imposer des exigences d'authentification supplémentaires lors de l'accès aux ressources protégées. La clé de configuration policies d'IAG permet aux administrateurs de spécifier le chemin qui sera protégé ainsi que la logique pour permettre ou refuser l'accès. La documentation des politiques d'accès IBM Security Verify détaille la liste des politiques d'authentification définies qui peuvent être appliquées.

L'extrait de code suivant démontre comment une seule page peut être protégée avec la politique "2FA toujours", qui incitera toujours l'utilisateur à compléter un défi 2FA avant de permettre l'accès.

    policies:
      authorization:
        - name: "enforce_2fa"
          paths:
            - "/tomcatsso/DemoApplication/secTestStepUp.jsp"
          rule: 'acr != "urn:ibm:security:policy:id:17"'
          action: "obligate"
          obligation:
            oidc:
              acr_values: "urn:ibm:security:policy:id:17"

Retour au guide d'intégration Tomcat

Serveur d'application Tomcat de démonstration : exemple d'intégration "hello world"

Ce guide peut être utilisé pour déployer une démonstration simple des capacités d'identité disponibles depuis IBM Security Verify et IBM Application Gateway (IAG). Cette démonstration fournit la configuration pour deux conteneurs : Un conteneur IAG configuré pour authentifier les utilisateurs avec IBM Security Verify ; et un conteneur Tomcat avec une application web java JSP de démonstration.

Cette démonstration est déployée sur Kubernetes mais pourrait être modifiée pour OpenShift ou une autre plateforme d'orchestration de conteneurs. Tous les fichiers de configuration plus des scripts supplémentaires pour aider au déploiement de cette démonstration peuvent être trouvés sur IBM Security Integrations. Une archive de l'application web de démonstration est disponible sur la page des releases.

Connaissances supposées

Pour déployer avec succès cette démonstration, il y a quelques connaissances supposées. Un utilisateur devrait être familier avec :

  • Le déploiement de conteneurs, config maps et secrets vers Kubernetes.
  • La création et gestion de locataires IBM Security Verify.

Prérequis

Pour déployer cette démonstration, un utilisateur devrait d'abord :

  • Récupérer les artefacts d'intégration requis depuis le répertoire tomcat du repo des intégrations de sécurité.
  • Configurer votre environnement pour se connecter au cluster Kubernetes (ou équivalent) utilisé pour héberger cette démonstration.
    • Vous aurez besoin d'un client API pour une application verify IAG ; de l'ICP pour sécuriser la connexion à la fois au serveur d'application et à IBM Security Verify ; et d'une application (ex l'application de démonstration) à déployer.

Configuration d'IBM Security Verify

L'identité pour cette démonstration est fournie par IBM Security Verify. Un guide pour configurer IBM Security Verify comme un OP pour IAG est disponible dans le README IAG

Créer/Demander l'ICP

Des clés asymétriques sont requises pour les connexions SSL et pour signer/vérifier les JWT. Les commandes openssl suivantes peuvent être utilisées pour générer des clés RSA et des certificats X509 auto-signés pour Tomcat et IBM Application Gateway. Le certificat/clé publique X509 utilisé par IBM Application Gateway pour les connexions aux serveurs jonctionnés devrait également être importé dans le magasin de clés PKCS12 (fichier .p12) utilisé par Tomcat. Pour les environnements de production, l'ICP utilisée devrait être signée par une autorité de certification appropriée.

# Créer les certificats/clés IAG
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:4096 -keyout iag.key -out iag.pem \
        -subj "/C=AU/ST=QLD/L=Gold Coast/O=IBM/CN=demo.iag.server"

# Créer les certificats/clés/pcsk12 Tomcat
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:4096 -keyout tomcat.key -out tomcat.pem \
        -subj "/C=AU/ST=QLD/L=Gold Coast/O=IBM/CN=demo.tomcat.server"
openssl pkcs12 -export -out tomcat.p12 -inkey tomcat.key -in tomcat.pem -passout pass:demokeystore

# Importer le X509 IAG dans le magasin de clés Tomcat
keytool -importcert -keystore tomcat.p12 -file iag.pem -alias isvajwt -storepass demokeystore -noprompt

Déploiement d'IBM Application Gateway

Une fois que l'application IBM Security Verify a été créée et l'ICP générée, l'application peut être déployée sur votre plateforme d'orchestration de conteneurs (OpenShift/Kubernetes). Il y a deux conteneurs requis pour cette démonstration : le conteneur IAG qui est configuré comme un RP OIDC pour l'OP IBM Security Verify précédemment configuré ; et le serveur d'application Tomcat qui est la cible de l'intégration. Le déploiement IAG nécessite trois objets Kubernetes : Une carte secrète pour les données sensibles ; une config map avec la configuration IAG ; et un déploiement qui définit les conteneurs IAG à déployer. Les sections suivantes détaillent comment ces objets sont créés.

Carte de secrets IAG

Les secrets Kubernetes sont utilisés pour obfusquer les données sensibles telles que l'id client et le secret de l'application IBM Security Verify. Les informations supplémentaires non sensibles telles que le fichier config.yaml et tous certificats/clés X509 devraient être ajoutées en utilisant des Config Maps.

apiVersion: v1
kind: Secret
metadata:
  name: ibm-verify-oidc-integration
type: Opaque
data:
  client_id: "change this"
  client_secret: "change this"

Config Map IAG

Le cœur d'un déploiement IAG est le fichier de configuration yaml qui définit les ressources protégées et les politiques d'accès. L'exemple suivant définit une jonction vers un serveur d'application Tomcat ainsi que la définition du JWT fourni au serveur. La configuration d'identité IBM Security Verify est également définie dans ce fichier. Si une option de configuration n'est pas capable d'être définie avec les options de configuration documentées, l'entrée advanced/configuration peut être utilisée pour définir les entrées de configuration du démon proxy inverse.

apiVersion: v1
kind: ConfigMap
metadata:
  name: ibm-verify-tomcat-integration-config
data:
  iag.pem: |
%%IAG_CERTIFICATE%%
  iag.key: |
%%IAG_KEY%%
  integration.target.pem: |
%%INTEGRATION_SERVER_CERTIFICATE%%
  verify_tenant_ca.pem: |
%%VERIFY_TENANT_CERT%%
  config.yaml: |
    version: 21.09
    server:
      ssl:
        front_end:
          certificate:
            - "@iag.pem"
            - "@iag.key"
    resource_servers:
      - path: "/tomcatsso"
        connection_type: ssl
        transparent_path: false
        sni: "demo.integration.server"
        mutual_auth:
          certificate_auth:
            certificate:
              - "@iag.pem"
              - "@iag.key"
        servers:
          - host: "tomcat-integration"
            port: 9443
            ssl:
              certificate:
                - "@integration.target.pem"
        identity_headers:
          jwt:
            hdr_name: "Authorization"
            certificate:
              - "@iag.pem"
              - "@iag.key"
            claims:
              - text: "www.ibm.com"
                name: iss
                type: string
              - attr: AZN_CRED_PRINCIPAL_NAME
                name: sub
                type: string
              - text: "demo.websphere.server"
                name: aud
                type: string
    advanced:
      configuration:
        - stanza: "jwt:/tomcatsso"
          entry: "hdr-format"
          operation: set
          value: "Bearer %TOKEN%"
    identity:
      oidc:
        client_id: secret:ibm-verify-oidc-integration/client_id
        client_secret: secret:ibm-verify-oidc-integration/client_secret
        discovery_endpoint: https://your.ibmcloudsecurity.com/oidc/endpoint/default/.well-known/openid-configuration
        redirect_uri_host: ibm.security.integration.demo:30443
        #mapped_identity: "{sub}"
        ssl:
          certificate:
            - "@verify_tenant_ca.pem"
        response_type: code
        response_mode: query

Déploiement IBM Application Gateway

Ensuite, nous devons définir le conteneur IBM Application Gateway et le connecter à la couche de service Kubernetes pour qu'il soit accessible depuis les adresses réseau extérieures au cluster Kubernetes. La version de conteneur utilisée devrait correspondre à la version définie dans le config.yaml de la ConfigMap. Les vérifications de santé du conteneur sont également définies pour permettre à Kubernetes de répondre si le conteneur IBM Application gateway cesse de répondre.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iag
  labels:
    app: iag
spec:
  selector:
    matchLabels:
      app: iag
  replicas: 1
  template:
    metadata:
      labels:
        app: iag
    spec:
      #serviceAccountName: ibm-application-gateway
      imagePullSecrets:
        - name: iag-login
      volumes:
        - name: integration-config
          configMap:
            name: ibm-verify-tomcat-integration-config
      containers:
        - name: iag
          image: ibmcom/ibm-application-gateway:21.09.0
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: integration-config
              mountPath: /var/iag/config
          readinessProbe:
            exec:
              command:
              - /sbin/health_check.sh
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            exec:
              command:
              - /sbin/health_check.sh
            initialDelaySeconds: 120
            periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
  name: iag
  labels:
    app: iag
spec:
  ports:
    - port: 8443
      name: iag
      protocol: TCP
      nodePort: 30443
  selector:
    app: iag
  type: NodePort

Déploiement du serveur Apache Tomcat de démonstration

La dernière étape de cette démonstration est de déployer le serveur Tomcat qui est la cible de cette intégration. Un conteneur Tomcat simple est fourni dans le cadre des ressources de démonstration. Ce conteneur est déjà configuré pour utiliser la valve JWT pour fournir des informations d'identité à l'application Java.

L'application de démonstration déployée sur le conteneur Tomcat est configurée pour refléter les informations d'identité fournies dans l'objet java Principal. Un magasin de clés PCKS12 est également monté sur le fichier de magasin de clés par défaut Tomcat qui assure que le certificat SSL fourni par IBM Application Gateway peut être validé par Tomcat (TLS mutuel).

apiVersion: v1
kind: ConfigMap
metadata:
  name: tomcat-config
binaryData:
  DemoApplication.war: %%DEMO_APPLICATION%%
  jose4j.jar: %%JOSE4J_JAR%%
  slf4j-api.jar: %%SLF4J_JAR%%
  jakrta_servlet_api.jar: %%JAKARTA_SERLVET_API_JAR%%
  jakrta_jacc.jar: %%JAKARTA_JACC_JAR%%
  ibm_security_jwt_valve.jar: %%IBM_SECURITY_JWT_VALVE_JAR%%
  DemoKeystore.p12: %%DEMO_KEYSTORE%%
data:
  server.xml: |
%%SERVER_XML%%
  logging.properties: |
%%LOGGING_PROPERTIES%%
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-integration
  labels:
    app: tomcat-integration
spec:
  selector:
    matchLabels:
      app: tomcat-integration
  replicas: 1
  template:
    metadata:
      labels:
        app: tomcat-integration
    spec:
      volumes:
        - name: tomcat-config
          configMap:
            name: tomcat-config
        - name: tomcat-lib
          emptyDir: {}
      containers:
        - name: tomcat-integration
          image: tomcat:latest
          args: ["catalina.sh", "run"]
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8443
          env:
            - name: JAVA_OPTS
              value: "-Djavax.net.debug=ssl:handshake"
          volumeMounts:
            - mountPath: /usr/local/tomcat/webapps/DemoApplication.war
              subPath: DemoApplication.war
              name: tomcat-config
            - mountPath: /usr/local/tomcat/conf/server.xml
              subPath: server.xml
              name: tomcat-config
            - mountPath: /usr/local/tomcat/conf/logging.properties
              subPath: logging.properties
              name: tomcat-config
            - mountPath: /usr/local/tomcat/DemoKeystore.p12
              subPath: DemoKeystore.p12
              name: tomcat-config
            - mountPath: /usr/local/tomcat/lib
              name: tomcat-lib
      initContainers:
        - name: permissions-fix
          image: tomcat:latest
          command: ["bash", "-c", "cp /temp/*.jar /tomcat_lib/; cp /usr/local/tomcat/lib/*.jar /tomcat_lib/; ls -lah /tomcat_lib"]
          volumeMounts:
            - mountPath: /temp
              name: tomcat-config
            - mountPath: /tomcat_lib
              name: tomcat-lib

---
apiVersion: v1
kind: Service
metadata:
  name: demo-tomcat-server
  labels:
    app: tomcat-integration
spec:
  ports:
    - port: 8443
      name: demo-tomcat-server
      nodePort: 31443
  selector:
    app: tomcat-integration
  type: NodePort