IBM Security Verify Intégration

IBM Verify SSO pour Tomcat à l'aide de IBM Application Gateway

IBM Verify peut être utilisé pour fournir une identité basée sur le nuage à 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. L'IAG peut également être utilisé pour mettre en œuvre des politiques d'authentification supplémentaires basées sur le chemin d'accès (telles que 2FA ) lorsque cela est nécessaire.

Connaissances supposées

Ce guide suppose que vous êtes familiarisé avec les applications IBM Verify et la gestion d'un registre d'utilisateurs basé sur le cloud. Les utilisateurs doivent également être familiarisés avec la configuration de IBM Application Gateway. Plus précisément, vous devez être en mesure de

  • Créez une nouvelle application IBM 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 familiarisés avec la configuration d' IBM Application Gateway (IAG). En particulier, vous devez être en mesure de configurer une source d'identité et un serveur de ressources. Vous devez également fournir l'infrastructure de clés publiques requise pour prendre en charge les connexions SSL entre IAG et le serveur jonctionné.

Prérequis

Pour utiliser ce guide, vous devez disposer de

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

Configurer IBM Verify

Le guide du scénario de vérification peut être utilisé pour configurer un locataire IBM Verify afin de fournir des capacités SSO à IBM Application Gateway. Une application IAG doit être créée ou mise à jour pour prendre en charge la nouvelle instance IAG. Cela impliquera probablement de modifier les entrées du site redirect_uri pour y inclure le nom de domaine ou d'hôte que l'instance IAG protège.

Le registre des utilisateurs doit également être configuré maintenant (si ce n'est pas déjà fait). IBM Verify prend en charge les utilisateurs de l'annuaire en nuage ainsi que les sources d'identité fédérées.

Déploiement de IBM Application Gateway

Pour configurer l'IAG afin qu'il transmette les informations d'identité de IBM 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é du 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é par / ) et un serveur de ressources doivent être définis. L'en-tête d'identité JWT et la configuration supplémentaire du jeton sont également définis 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, il devrait s'agir du service créé pour le déploiement Tomcat cible. Le certificat X509 (ou le certificat du signataire) configuré pour l'authentification mutuelle (par exemple : iag.pem ) doit être un certificat de confiance dans le magasin de clés utilisé par Tomcat.

L'émetteur ( iss ), l'audience ( aud ) et le sujet ( sub ) configurés pour le JWT doivent correspondre à la configuration définie dans la configuration XML du serveur Tomcat. La PKI utilisée pour signer (et crypter) le JWT généré doit également être importée dans le keystore utilisé par le serveur Tomcat. Tomcat ne prend en charge que l'utilisation de l'en-tête Authorization pour fournir des JWT et doit ê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é d'identité peut être utilisée pour configurer IAG en tant que RP OIDC. Vous pouvez utiliser l'application IBM Verify créée ici pour fournir des informations d'identité à IAG. L'exemple fourni utilise également des types de données spéciales que IAG expose pour obscurcir les informations sensibles qui peuvent être nécessaires pour définir votre déploiement. Dans ce cas, l'identifiant et le secret du client pour l'application IBM Verify sont stockés dans un secret Kubernetes au lieu d'une carte de configuration ou définis dans le fichier de déploiement.

La définition de oidc met également en correspondance l'attribut preferred_username au lieu de l'attribut sub renvoyé dans les réclamations de Verify. Cela permet de renvoyer un attribut reconnaissable par l'homme en tant que nom principal disponible pour 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 afin de fournir un JWT dans le bon format. Le format de l'en-tête doit être modifié pour inclure la chaîne statique Bearer. Le nom de la strophe de cette propriété dépend du nom de la jonction avec le serveur Tomcat. Si un nom de jonction différent est utilisé, la clé de strophe doit être mise à jour à jwt:/<junction name>.

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

Authentification par un second facteur ( 2FA ) avec IBM Verify

Un certain nombre de politiques d'authentification supplémentaires peuvent être appliquées aux ressources protégées afin de mettre en œuvre des exigences d'authentification supplémentaires lors de l'accès aux ressources protégées. La clé de configuration des politiques IAG permet aux administrateurs de spécifier les chemins d'accès qui seront protégés ainsi que la logique d'autorisation ou de refus d'accès. La documentation sur les politiques d'accès de IBM Verify détaille la liste des politiques d'authentification définies qui peuvent être appliquées.

L'extrait de code suivant montre comment une seule page peut être protégée par la politique "2FA always", qui invitera toujours l'utilisateur à remplir un formulaire 2FA avant d'autoriser 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 de Tomcat

Démonstration du serveur d'application Tomcat : "Exemple d'intégration "hello world

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

Cette démo 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 ainsi que des scripts supplémentaires destinés à faciliter le déploiement de cette démo sont disponibles sur le site IBM Security Integrations. Une archive de l'application web de démonstration est disponible sur la page des versions.

Connaissances supposées

Pour réussir cette démonstration, certaines connaissances sont nécessaires. Un utilisateur doit être familier avec :

  • Déployer des conteneurs, des cartes de configuration et des secrets dans Kubernetes.
  • Création et gestion des locataires IBM Verify.

Prérequis

Pour déployer cette démo, l'utilisateur doit tout d'abord

  • Récupérer les artefacts d'intégration nécessaires dans le répertoire tomcat du repo security Integrations.
  • Configurez votre environnement pour vous connecter au cluster Kubernetes (ou équivalent) utilisé pour héberger cette démo.
    • Vous aurez besoin d'un client API pour une application de vérification IAG, d'une ICP pour sécuriser la connexion au serveur d'application et à IBM Verify, et d'une application (par exemple l'application de démonstration ) à déployer.

Configuration IBM Verify

L'identité de cette démo est fournie par IBM Verify. Un guide pour la configuration de IBM Verify en tant qu'OP pour IAG est disponible dans le Readme d'IAG

Créer/demander une ICP

Les clés asymétriques sont nécessaires 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 X509 et la clé publique utilisés par IBM Application Gateway pour les connexions aux serveurs jonctionnés doivent également être importés dans le keystore PKCS12 (fichier .p12 ) utilisé par Tomcat. Pour les environnements de production, l'ICP utilisée doit être signée par une autorité de certification appropriée.

# Create IAG certificates/keys
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"

# Create Tomcat certificae/keys/pcsk12
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

# Import IAG X509 into the Tomcat keystore
keytool -importcert -keystore tomcat.p12 -file iag.pem -alias isvajwt -storepass demokeystore -noprompt

Déploiement de IBM Application Gateway

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

Carte IAG Secrets

Kubernetes les secrets sont utilisés pour obscurcir des données sensibles telles que l'identifiant du client et le secret de l'application IBM Verify. Des informations supplémentaires non sensibles telles que le fichier config.yaml et tous les certificats/clés X509 doivent être ajoutés à l'aide des cartes de configuration.

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

Carte de configuration IAG

Le fichier de configuration yaml, qui définit les ressources protégées et les politiques d'accès, est au cœur du déploiement de l'IAG. L'exemple suivant établit une jonction avec un serveur d'application Tomcat et définit le JWT fourni au serveur. IBM Verify la configuration de l'identité est également définie dans ce fichier. Si une option de configuration ne peut pas ê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

IBM Application Gateway déploiement

Ensuite, nous devons définir le conteneur IBM Application Gateway et le connecter à la couche de service Kubernetes afin qu'il soit accessible à partir d'adresses réseau extérieures au cluster Kubernetes. La version du conteneur utilisée doit correspondre à la version définie dans le ConfigMap config.yaml. Des contrôles de santé des conteneurs sont également définis pour permettre à Kubernetes de réagir 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

L'étape finale de cette démo consiste à déployer le serveur Tomcat qui est la cible de cette intégration. Un simple conteneur Tomcat est fourni avec les ressources de la démonstration. Ce conteneur est déjà configuré pour utiliser la valve JWT afin de fournir des informations d'identité à l'application Java.

L'application de démonstration déployée dans le conteneur Tomcat est configurée pour refléter les informations d'identité fournies dans l'objet Java Principal. Un keystore PCKS12 est également monté dans le fichier keystore par défaut de Tomcat, ce qui garantit 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