Authentifizierungsmethode des Konsumenten des Benutzernamenstokens mit einem JAAS-Anmeldemodul in einem Stack ersetzen

Standardmäßig ist UNTConsumeLoginModule, der Web Services Security-Benutzernamenstokenkonsument, so definiert, dass der Benutzername und das Kennwort, die im Token enthalten sind, immer anhand der WebSphere-Registry validiert werden. Mit den von der GenericSecurityTokenFactory bereitgestellten SPIs können Sie die Authentifizierungsmethode umgehen.

Informationen zu diesem Vorgang

Wenn Sie die von UNTConsumeLoginModule verwendete Authentifizierungsmethode umgehen möchten, müssen Sie ein eigenes angepasstes JAAS-Anmeldemodul bereitstellen, das die Authentifizierung durchführt. Das angepasste Anmeldemodul befindet sich in einer angepassten JAAS-Konfiguration im Stack unterhalb von UNTConsumeLoginModule. UNTConsumeLoginModule konsumiert und validiert die Token-XML. Die Validierung der für den Benutzernamen und das Kennwort angegebenen Werte erfolgt durch das angepasste Anmeldemodul im Stack.

Weil mit UNTConsumeLoginModule die Annahme verbunden ist, dass Benutzername und Kennwort authentifiziert werden, muss ein Anmeldemodul im Stack, das für die Ausführung diese Funktion vorgesehen wird, höhere Anforderungen erfüllen als Anmeldemodule, die lediglich eine dynamische Tokenfunktionalität bereitstellen.

Wenn Sie für UNTConsumeLoginModule festlegen möchten, dass keine Authentifizierung von Benutzername und Kennwort erfolgen soll, müssen Sie im konfigurierten Callback-Handler die folgende Eigenschaft angeben:

com.ibm.wsspi.wssecurity.token.UsernameToken.authDeferred=true

Wie die meisten WS-Security-Anmeldemodule versetzt UNTConsumeLoginModule das konsumierte Token immer in die Map für gemeinsamen Status, auf die alle Anmeldemodule im Stack Zugriff haben. Wenn authDeferred=true angegeben ist, stellt UNTConsumeLoginModule während der Festschreibungsphase (Commit) sicher, dass dasselbe UsernameToken-Objekt, das ursprünglich in den gemeinsamen Status gesetzt wurde, an einer anderen Position in den gemeinsamen Status versetzt wurde. Wird dieses UsernameToken-Objekt nicht gefunden, wird eine Ausnahme des Typs LoginException ausgelöst. Daher ist es nicht möglich, lediglich im Callback-Handler authDeferred=true festzulegen, ohne dass ein zugehöriges Anmeldemodul das Token in den gemeinsamen Status zurückversetzt.

Vorgehensweise

  1. Entwickeln Sie ein JAAS-Anmeldemodul, das die Authentifizierung ausführt, und machen Sie es für Ihren Anwendungscode verfügbar. Dieses neue Anmeldemodul wird im Stack unterhalb von com.ibm.ws.wssecurity.wssapi.token.impl.UNTConsumeLoginModule angeordnet.

    Dieses Anmeldemodul muss folgende Aufgaben ausführen:

    1. Das von UNTConsumeLoginModule konsumierte Benutzernamenstoken mit der folgenden Methode abrufen:
      UsernameToken unt = (UsernameToken)factory.getConsumerTokenFromSharedState(sharedState,UsernameToken.ValueType);
      In diesem Codebeispiel ist "factory" eine Instanz von com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory.
    2. Den Benutzernamen und das Kennwort in der festgelegten Art und Weise prüfen.

      Sie können unt.getUsername() und unt.getPassword() aufrufen, um den Benutzernamen und das Kennwort abzurufen.

      Das Anmeldemodul sollte bei einem Authentifizierungsfehler eine Ausnahme des Typs "LoginException" auslösen.

    3. Das Benutzernamenstoken, das im vorherigen Schritt abgerufen wurde, wieder in den gemeinsamen Status (Shared State) versetzen.

      Verwenden Sie dazu die folgende Methode:

      factory.putAuthenticatedTokenToSharedState(sharedState, unt);

    Es folgt ein Beispiel für ein Anmeldemodul:

    package test.tokens;
    
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.security.auth.Subject;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
    
    import java.util.ArrayList;
    
    import com.ibm.wsspi.security.registry.RegistryHelper;
    import com.ibm.websphere.security.UserRegistry;
    
    public class MyUntAuthenticator implements LoginModule {
    
      private Map _sharedState;
      private Map _options;
      private CallbackHandler _handler;
    
      public void initialize(Subject subject, CallbackHandler callbackHandler,
                             Map<String, ?> sharedState, Map<String, ?> options) {
    
        this._handler = callbackHandler;
        this._sharedState = sharedState;
        this._options = options;  
      }
    
      public boolean login() throws LoginException {
        //Aus Gründen der Lesbarkeit ist dieses Anmeldemodul so
      //aufgebaut, dass es nicht vor allen Nullzeigerausnahmen (NPEs) schützt
    
        GenericSecurityTokenFactory factory = null;
        WSSUtilFactory utilFactory = null;
        try  {    
          factory = GenericSecurityTokenFactory.getInstance();
          utilFactory = WSSUtilFactory.getInstance();
        } catch (Exception e)  {
          throw new LoginException(e.toString());
        }
        if (factory == null) {
          throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
        }
    
        UsernameToken unt = (UsernameToken)factory.getConsumerTokenFromSharedState(this._sharedState,UsernameToken.ValueType);
    
        String username = unt.getUsername();
        char [] password = unt.getPassword();
    
        ////Benutzernamen und Kennwort authentifizieren,
        //um ein PasswordDigest-Kennwort zu validieren
        //String pw = yourCodeToLookUpPasswordForUsername(username);
        //boolean match = utilFactory.verifyDigestedPassword(unt, pw.toCharArray());
        //if (!match) throw new LoginException("Digested passwords do not match");
        //Beispiel:
        try  {    
          simpleUserGroupCheck(username, password, "cn=group1,o=ibm,c=us");
        } catch (Exception e)  {
          LoginException le = new LoginException(e.getMessage());
          le.initCause(e);
          throw le;
        }
    
        //Authentifiziertes Token in den gemeinsamen Status versetzen
        factory.putAuthenticatedTokenToSharedState(this._sharedState, unt);
    
        return true;
      }
    
      private boolean simpleUserGroupCheck(String username, char [] password, String group) throws Exception {
        String allowedGroup = null;
    
        //Standardbenutzerregistry abrufen
        UserRegistry user_reg = RegistryHelper.getUserRegistry(null);
    
        //Benutzer anhand Benutzerregistry authentifizieren
        user_reg.checkPassword(username, new String(password));
    
        //Liste der Gruppen abrufen, zu denen der Benutzer gehört
        java.util.List<String> groupList = user_reg.getGroupsForUser(username);
    
        //fest codierte Gruppe verwenden
        allowedGroup = group;
    
        //oder den Wert aus der eigenen angepassten Eigenschaft des Callback-Handlers abrufen
        //WSSUtilFactory util = WSSUtilFactory.getInstance();
        //Map map = util.getCallbackHandlerProperties(this._handler);
        //allowedGroup = (String) map.get("MY_ALLOWED_GROUP_1");
    
        //prüfen, ob der Benutzer zur zulässigen Gruppe gehört
        if (!groupList.contains(allowedGroup)) {
          throw new LoginException("user ["+username+"] is not in allowed group ["+allowedGroup+"]");
        }
        return true;
    }
      //Implementierung der übrigen Methoden, die die Schnittstelle des Anmeldemoduls
      //(LoginModule) erfordert.
    }
  2. Erstellen Sie eine neue JAAS-Anmeldekonfiguration.
    1. Klicken Sie in der Administrationskonsole auf Sicherheit > Globale Sicherheit.
    2. Wählen Sie unter "Authentifizierung" Java Authentication and Authorization Service aus.
    3. Wählen Sie Systemanmeldungen aus.
    4. Klicken Sie auf Neu, und geben Sie Alias = test.consume.unt an.
    5. Klicken Sie auf Neu und wählen Sie Sie Name der Modulklasse = com.ibm.ws.wssecurity.wssapi.token.impl.UNTConsumeLoginModule aus.
    6. Klicken Sie auf Neu, und geben Sie Name der Modulklasse = test.tokens.MyUntAuthenticator an.
    7. Wählen Sie Proxy für Anmeldemodul verwenden aus.
    8. Klicken Sie auf OK und anschließend auf Speichern.
  3. Konfigurieren Sie den Konsumenten des Benutzernamenstokens für die Verwendung der neuen JAAS-Konfiguration.
    1. Öffnen Sie die Bindungskonfiguration, die geändert werden soll.

      Wählen Sie in der Administrationskonsole WS-Security > Authentifizierung und Zugriffsschutz aus.

    2. Wählen Sie unter "Authentifizierungstoken" das eingehende Benutzernamenstoken aus, das Sie ändern möchten.
    3. Wählen Sie JAAS-Anmeldung = test.consume.unt aus.
  4. Legen Sie die erforderliche Eigenschaft in dem Callback-Handler fest, der für den Konsumenten des Benutzernamenstokens konfiguriert ist.
    1. Klicken Sie auf Callback-Handler.
    2. Fügen Sie die angepasste Eigenschaft com.ibm.wsspi.wssecurity.token.UsernameToken.authDeferred=true hinzu.
    3. Klicken Sie auf OK.
  5. Klicken Sie auf Speichern.
  6. Starten Sie den Anwendungsserver erneut, um die JAAS-Konfigurationsänderungen anzuwenden.
  7. Testen Sie Ihren Service.

Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_replace_authmethod_usernametoken
Dateiname:twbs_replace_authmethod_usernametoken.html