Asserteur d’identité WebLogic
Le module Maverics Identity Asserter est un module personnalisé d’assertion d’identité WebLogic. Ce module valide le fait qu’une requête provient d’un proxy d’authentification tiers fiable, analyse l’identité de l’utilisateur à partir de l’en-tête de la requête et renvoie un nom distinctif (DN, Distinguished Name) ou un nom court que WebLogic utilisera pour construire son contexte d’identité.
Exigences relatives au serveur
- Oracle WebLogic 12c
- Java 8
Installation
Pour installer l’asserteur d’identité, copiez-le dans le répertoire $WL_HOME/server/lib/mbeantypes
($WL_HOME
correspond au répertoire d’origine du serveur WebLogic).
- Sous le domaine cible, sélectionnez « Security Realms ».
- Sélectionnez le domaine cible, par exemple « myrealm », puis sélectionnez « Providers » -> « Authentication ».
- Créez un nouveau fournisseur d’authentification de type « MavericsIdentityAsserter ».
- Une fois le fournisseur créé, réorganisez les modules de sécurité en déplaçant l’asserteur qui vient d’être créé au début de la liste.
- Sélectionnez la valeur
SUFFICIENT
pour l’indicateur Strata Identity Asserter. - Générez la clé de vérification de la signature encodée au format base64, comme indiqué dans l’exemple ci-dessous.
- Sélectionnez l’onglet « Provider Specific » et ajoutez la clé encodée au format base64 que vous avez créée.
- Pour tous les autres modules de sécurité, sélectionnez la valeur
SUFFICIENT
pour l’indicateur. - Redémarrez le serveur WebLogic.
- Testez la fonctionnalité en accédant à l’URL.
Mise à niveau
Pour mettre l’asserteur d’identité à niveau, remplacez la version existante de Maverics Identity Asserter dans
le répertoire $WL_HOME/server/lib/mbeantypes
par une nouvelle version. Après avoir remplacé le
JAR, redémarrez le serveur WebLogic.
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 WebLogic. Une fois la requête reçue par WebLogic, l’asserteur d’identité
validera la valeur de l’en-tête MAVERICS_USERNAME
et construira le
contexte d’identité.
La commande 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 webLogicPrivateKey
.
openssl genrsa -out wl-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 wl-private-key.pem -outform PEM -pubout -out wl-public-key.pem
Une fois la clé publique extraite, il faut l’encoder en base64 avant de l’ajouter en tant que propriété dans WebLogic. L’encodage Base64 de la clé est nécessaire car WebLogic n’autorise pas les propriétés multi-lignes.
openssl base64 -A -in wl-public-key.pem
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 à WebLogic, le fichier de configuration Maverics ci-dessous peut être utilisé comme référence pour transmettre une valeur d’en-tête JWT à WebLogic.
apps:
- name: exampleWebLogic
type: proxy
routePatterns:
- /
upstream: https://app-internal.example.com
headers:
- createHeaderSE:
funcName: CreateHeader
file: /etc/maverics/webLogic-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: webLogicPrivateKey
# 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/webLogic-createHeader.go
package main
import (
"errors"
"fmt"
"net/http"
"time"
"github.com/strata-io/service-extension/orchestrator"
"github.com/strata-io/service-extension/weblogic"
)
// CreateHeader creates an HTTP header that will be consumed and validated by
// the WebLogic Identity Asserter. 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 WebLogic")
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.WebLogic().NewSignedJWT(weblogic.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
}