Module Maverics WebSphere TAI
Le module Maverics TAI est un WebSphere Trust Association Interceptor (TAI). Ce module valide le fait que la requête provient d’un proxy d’authentification tiers fiable, lit l’identité de l’utilisateur à partir de l’en-tête de la requête et renvoie un nom distinctif (DN) ou un nom court que Websphere associera à un utilisateur dans son registre.
Exigences relatives au serveur
- IBM Websphere 8.5
- Java 8
Installation
Copiez le dernier fichier JAR Maverics TAI dans le répertoire d’installation WebSphere,
<WEBSPHERE_ROOT>/AppServer/lib/ext
.
Dans la console d’administration WebSphere :
- Sous Security dans le menu de gauche, sélectionnez Global Security
- Sous Authentication, développez la Web and SIP security et sélectionnez Trust association
- Assurez-vous que l’option Enable trust association est sélectionnée et accédez à Interceptors
- Cliquez sur New… et ajoutez un nouvel intercepteur avec le nom de classe
io.strata.TAIModule
- Ajoutez des propriétés pour configurer l’intercepteur
- Redémarrez Websphere
Mise à niveau
Supprimez le fichier JAR Maverics TAI existant du répertoire d’installation de WebSphere,
et ajoutez la dernière version au fichier <WEBSPHERE_ROOT>/AppServer/lib/ext
.
Une fois le dernier fichier JAR ajouté, redémarrez Websphere.
Options de configuration
headerName
headerName
correspond au nom de l’en-tête utilisé pour lire de nom d’utilisateur. Si aucune n’est
fournie, la valeur par défaut MAVERICS_USERNAME
est utilisée. Par défaut, le module TAI
suppose que la valeur de l’en-tête est un JWT signé. Le nom d’utilisateur sera
extrait de la sous
-réclamation dans le JWT.
signatureVerificationKey
signatureVerificationKey
correspond à la clé publique RSA utilisée pour vérifier la signature de la
valeur de l’en-tête JWT. La clé publique doit être encodée au format base64 avant d’être ajoutée en tant que
propriété. Suivez les instructions fournies dans l’exemple ci-dessous pour générer une paire de clés
et encoder la clé publique au format base64.
insecurePlainTextHeader
insecurePlainTextHeader
peut être utilisé pour remplacer le comportement par défaut du TAI de sorte que
la valeur du MAVERICS_USERNAME
soit un nom d’utilisateur en texte brut au lieu d’un JWT signé.
Lorsque cette option est utilisée, l’intercepteur devient réceptif au trafic latéral.
Exemple
Cet exemple illustre la manière dont l’orchestrateur peut être utilisé pour authentifier un utilisateur et
acheminer le trafic à travers un proxy vers WebSphere. Lorsqu’une requête est reçue par WebSphere, le module TAI
valide la valeur de l’en-tête MAVERICS_USERNAME
et construit le contexte d’identité dans
WebSphere.
La commande suivante suivante peut être exécutée
afin de générer une clé privée qui sera utilisée pour signer les jetons JWT. Dans cet exemple, la clé privée générée est stockée dans une base de données secrète
dont le nom est taiPrivateKey
.
openssl genrsa -out tai-private-key.pem 2048
Une fois la clé privée générée, la clé publique utilisée pour vérifier la signature peut être extraite à l’aide de la commande suivante.
openssl rsa -in tai-private-key.pem -outform PEM -pubout -out tai-public-key.pem
Une fois la clé publique extraite, elle doit être encodée au format base64 avant d’être ajoutée en tant que propriété dans WebSphere. L’encodage Base64 de la clé est nécessaire car WebSphere n’autorise pas les propriétés multi-lignes.
openssl base64 -A -in tai-public-key.pem
Exemple de la propriété de clé encodée au format Base64 ajoutée dans WebSphere.
Maintenant que la paire de clés a été générée et que les propriétés nécessaires ont été ajoutées à Websphere, le fichier de configuration Maverics ci-dessous peut être utilisé comme référence pour transmettre une valeur d’en-tête JWT à WebSphere.
apps:
- name: exampleTAI
type: proxy
routePatterns:
- /
upstream: https://app-internal.example.com
headers:
- createHeaderSE:
funcName: CreateHeader
file: /etc/maverics/tai-createHeader.go
metadata:
# userLookupKey is the key that will be used to look up the user's
# username from the session store. The corresponding value will be passed
# as the 'sub' claim in the JWT.
userLookupKey: azure.name
# privateKeyLookupKey is the key that will be used to retrieve the
# signing key from the secret store.
privateKeyLookupKey: taiPrivateKey
# jwtLifetime is the lifetime of the JWT in hours. The value should be
# set to match the lifetime of a user's session.
jwtLifetime: 24
policies:
- location: /
authentication:
idps:
- azure
authorization:
allowAll: true
/etc/maverics/tai-createHeader.go
package main
import (
"errors"
"fmt"
"net/http"
"time"
"github.com/strata-io/service-extension/orchestrator"
"github.com/strata-io/service-extension/tai"
)
// CreateHeader creates an HTTP header that will be consumed and validated by the TAI
// module. The header has a name of 'MAVERICS_USERNAME' and a signed JWT as the value.
func CreateHeader(
api orchestrator.Orchestrator,
_ http.ResponseWriter,
_ *http.Request,
) (http.Header, error) {
logger := api.Logger()
logger.Debug("se", "creating header for TAI")
metadata := api.Metadata()
userLookupKey, _ := metadata["userLookupKey"].(string)
privateKeyLookupKey, _ := metadata["privateKeyLookupKey"].(string)
jwtLifetime, _ := metadata["jwtLifetime"].(int)
session, err := api.Session()
if err != nil {
return nil, fmt.Errorf("failed to get session: %w", err)
}
name, err := session.GetString(userLookupKey)
if err != nil {
return nil, fmt.Errorf("failed to retrieve username from session: %w", err)
}
secretProvider, err := api.SecretProvider()
if err != nil {
return nil, fmt.Errorf("failed to retrieve secret provider: %w", err)
}
privateKey := secretProvider.GetString(privateKeyLookupKey)
if len(privateKey) == 0 {
return nil, errors.New("private key not found in secret provider")
}
jwt, err := api.TAI().NewSignedJWT(tai.Config{
RSAPrivateKeyPEM: privateKey,
Subject: name,
Lifetime: time.Duration(jwtLifetime) * time.Hour,
})
if err != nil {
return nil, fmt.Errorf("failed to construct JWT: %w", err)
}
header := make(http.Header)
header["MAVERICS_USERNAME"] = []string{jwt}
return header, nil
}