IBM Security Verify Intégration

IBM Security Verify SSO pour Liberty 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 faire appliquer des politiques d'authentification supplémentaires basées sur le chemin (telles que la 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é IAG.
  • Configurer un serveur de ressources IAG.
  • Définir la configuration SSL
    • Clé/certificat SSL pour le trafic https.
    • SSL mutuel pour les serveurs de ressources protégés.
    • Fortement recommandé pour le trafic web Liberty et IAG.

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 Liberty 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 à Liberty, 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. Les en-têtes d'identité (ou JWT) et la configuration de sécurité supplémentaire sont également définis ici pour le serveur Liberty 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 Liberty 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 Liberty.

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 Liberty. 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 Liberty. Liberty 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: "/libertysso"
    connection_type: ssl
    transparent_path: false
    sni: "demo.integration.server"
    mutual_auth:
      certificate_auth:
        certificate:
          - "@iag.pem"
          - "@iag.key"
    servers:
      - host: "liberty.integration.server"
        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

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 Liberty. 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:/libertysso"
          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:
            - "/libertysso/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 Liberty

Serveur d'application Liberty 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 Liberty avec une application java 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

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 liberty 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 Liberty 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 (fichier .p12) utilisé par Liberty. 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 Liberty
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:4096 -keyout liberty.key -out liberty.pem \
        -subj "/C=AU/ST=QLD/L=Gold Coast/O=IBM/CN=demo.liberty.server"
openssl pkcs12 -export -out liberty.p12 -inkey liberty.key -in liberty.pem -passout pass:demokeystore

# Importer le X509 IAG dans le magasin de clés Liberty
keytool -importcert -keystore liberty.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 Liberty 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 Liberty 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-liberty-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: "/libertysso"
        connection_type: ssl
        transparent_path: false
        sni: "demo.liberty.server"
        mutual_auth:
          certificate_auth:
            certificate:
              - "@iag.pem"
              - "@iag.key"
        servers:
          - host: "liberty-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
              - attr: groups
                name: groups
                type: string
    advanced:
      configuration:
        - stanza: "jwt:/libertysso"
          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://%%VERIFY_TENANT%%/oidc/endpoint/default/.well-known/openid-configuration
        redirect_uri_host: ibm.security.integration.demo:30443
        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-liberty-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 IBM Liberty de démonstration

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

L'application de démonstration déployée sur le conteneur Liberty 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 Liberty qui assure que le certificat SSL fourni par IBM Application Gateway peut être validé par Liberty (TLS mutuel).

apiVersion: v1
kind: ConfigMap
metadata:
  name: liberty-config
data:
  server.xml: |
    %%SERVER_XML%%
binaryData:
  DemoApplication.war: %%DEMO_APPLICATION%%
  DemoKeyStoreFile.p12: %%LIBERTY_KEYSTORE%%
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liberty-integration
  labels:
    app: liberty-integration
spec:
  selector:
    matchLabels:
      app: liberty-integration
  replicas: 1
  template:
    metadata:
      labels:
        app: liberty-integration
    spec:
      volumes:
        - name: liberty-config
          configMap:
            name: server-xml
      containers:
        - name: liberty-integration
          image: websphere-liberty:latest
          args: ["/opt/ibm/wlp/bin/server", "run", "defaultServer"]
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9443
          volumeMounts:
            - mountPath: /opt/ibm/wlp/output/defaultServer/resources/security/DemoKeyStoreFile.p12
              subPath: DemoKeyStoreFile.p12
              name: liberty-config
            - mountPath: /opt/ibm/wlp/usr/servers/defaultServer/dropins/DemoApplication.war
              subPath: DemoApplication.war
              name: liberty-config
            - mountPath: /opt/ibm/wlp/usr/servers/defaultServer/server.xml
              subPath: server.xml
              name: liberty-config
---
apiVersion: v1
kind: Service
metadata:
  name: liberty-integration
  labels:
    app: liberty-integration
spec:
  ports:
    - port: 9443
      name: liberty-integration
  selector:
    app: liberty-integration
  type: NodePort