Der Generator und der Konsument für generisch ausgegebene Token,
GenericIssuedTokenGenerateLoginModule und
GenericIssuedTokenConsumeLoginModule, können zusammen mit
den SPIs von
GenericSecurityTokenFactory und GenericSecurityToken verwendet werden, um
für ein angepasstes Token eine End-to-End-Lösung zu implementieren. Das Generieren und Konsumieren angepasster Token mit
den Anmeldemodulen für generische Tokenausgabe
kann entweder über Richtlinien und Bindungen oder
mit WSSAPIs erfolgen.
Vorbereitende Schritte
Sie müssen über einen Satz von funktionsfähigen JAX-WS-Service-Client und -Provideranwendungen
verfügen, denen Sie neue JAAS-Anmeldemodulklassen hinzufügen können.
Informationen zu diesem Vorgang
Führen Sie die folgenden Schritte aus, wenn
einem Satz von
JAX-WS-Service-Client und -Provideranwendungen die Verwendung eines angepassten Tokens ermöglicht werden soll.
In den folgenden
Schritten ist
MyToken der Name des Tokens, das erstellt wird.
Die Ausführung dieser Task hat folgende Verlauf:
- Es werden zwei JAAS-Anmeldemodule erstellt, eines zum Generieren und eines zum Konsumieren des Tokens.
- Das Token wird mit Unterstützung des Konsumenten und Generators für generisch ausgegebene Token
generiert und konsumiert.
- Anschließend werden
die Sicherheitsvorgaben auf die Anwendungen mit den Richtliniensätzen und Bindungen angewendet.
Vorgehensweise
- Erstellen Sie das folgende Generator-JAAS-Anmeldemodul und machen Sie es für Ihren Anwendungscode verfügbar.
package test.tokens;
import java.util.ArrayList;
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 javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.namespace.QName;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
public class MyCustomGenerator 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 {
GenericSecurityTokenFactory factory = null;
try {
factory = GenericSecurityTokenFactory.getInstance();
} catch (Exception e) {
throw new LoginException(e.toString());
}
if (factory == null) {
throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
}
SecurityToken myToken = null;
try {
SOAPElement tokenElement = createCustomElement(factory);
myToken = factory.getToken(tokenElement, new QName("http://www.acme.com","MyToken"));
} catch (Exception e) {
throw new LoginException(e.toString());
}
if (myToken == null) {
throw new LoginException("myToken is null");
}
//Token in einer Liste in den Status für gemeinsame Nutzung (shared state) setzen,
//damit es von den im Stack enthaltenen Anmeldemodulen genutzt werden kann
factory.putGeneratorTokenToSharedState(_sharedState, myToken);
return true;
}
private SOAPElement createCustomElement(GenericSecurityTokenFactory gstFactory) throws Exception {
/*
<acme:MyToken xmlns:acme="http://www.acme.com"
xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
<acme:EMail>joe.smith@acme.com</acme:EMail>
</acme:MyToken>
*/
SOAPFactory factory = SOAPFactory.newInstance();
//Element MyToken erstellen
SOAPElement tokElement = factory.createElement("MyToken", "acme", "http://www.acme.com");
//Attribut Id hinzufügen
tokElement.addAttribute(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", "utl"), gstFactory.createUniqueId());
//Element Email erstellen
SOAPElement emailElement = factory.createElement("Email", "acme", "http://www.acme.com");
emailElement.addTextNode("joe.smith@acme.com");
//Element EMail zu MyToken hinzufügen
tokElement.addChildElement(emailElement);
return tokElement;
}
public boolean logout() throws LoginException {
return false;
}
public boolean abort() throws LoginException {
return false;
}
public boolean commit() throws LoginException {
return true;
}
}
- Erstellen Sie das folgende Kosumenten-JAAS-Anmeldemodul und machen Sie es für Ihren Anwendungscode verfügbar.
package test.tokens;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMElement;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.ibm.websphere.wssecurity.callbackhandler.PropertyCallback;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.wsspi.wssecurity.wssapi.OMStructure;
public class MyCustomConsumer implements LoginModule {
private CallbackHandler _handler;
private Map _sharedState;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options) {
this._handler = callbackHandler;
this._sharedState = sharedState;
}
public boolean login() throws LoginException {
PropertyCallback propertyCallback = new PropertyCallback(null);
Callback[] callbacks = new Callback[] { propertyCallback};
try {
this._handler.handle(callbacks);
} catch (Exception e) {
throw new LoginException(e.toString());
}
//GenericSecurityTokenFactory abrufen
GenericSecurityTokenFactory factory = null;
try {
factory = GenericSecurityTokenFactory.getInstance();
} catch (Exception e) {
throw new LoginException(e.toString());
}
if (factory == null) {
throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
}
//Das vom GenericIssuedConsumeLoginModule konsumierte Token abrufen
SecurityToken myToken = factory.getConsumerTokenFromSharedState(_sharedState,
new QName("http://www.acme.com","MyToken"));
if (myToken == null) {
throw new LoginException("no token");
}
//Tokenelement abrufen
Object obj = myToken.getXML();
if (obj == null) {
throw new LoginException("token is empty");
}
if (!(obj instanceof OMStructure)) {
throw new LoginException("XML is not OMStructure");
}
OMElement tokenElement = ((OMStructure)obj).getNode();
//wenn mit einem w3c.dom-Element anstelle eines Axiom-Elements gearbeitet
//werden soll, kann die Methode org.apache.axis2.util.XMLUtils.toDOM
//verwendet werden
//Inhalt des Tokenelements verarbeiten
OMElement el = tokenElement.getFirstChildWithName(new QName("http://www.acme.com","Email"));
if (el == null) {
throw new LoginException("no email element");
}
String value = el.getText();
if (value != null && value.equals("joe.smith@acme.com")) {
return true;
} else {
throw new LoginException("email value is bad");
}
}
public boolean commit() throws LoginException {
return true;
}
public boolean logout() throws LoginException {
return false;
}
public boolean abort() throws LoginException {
return false;
}
}
- Erstellen Sie neue JAAS-Anmeldekonfigurationen.
- Wählen Sie in der Administrationskonsole
Sicherheit -> Globale Sicherheit aus.
- Wählen Sie unter "Authentifizierung"
Java Authentication and Authorization Service aus.
- Wählen Sie
Systemanmeldungen aus.
- Erstellen Sie zunächst den Generator mit dem angepassten Modul.
- Klicken Sie auf
Neu, und geben Sie Alias = test.generate.custom an.
- Klicken Sie auf
Neu, und geben Sie
Name der Modulklasse = test.tokens.MyCustomGenerator an.
- Wählen Sie
Proxy für Anmeldemodul verwenden aus.
- Klicken Sie auf OK.
- Klicken Sie auf
Neu, und wählen Sie
Name der Modulklasse = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenGenerateLoginModule aus.
- Klicken Sie auf OK.
- Klicken Sie auf
JAAS - Systemanmeldungen.
- Erstellen Sie zuletzt den Konsumenten mit dem angepassten Modul.
- Klicken Sie auf Neu, und geben Sie
Alias
= test.consume.custom an.
- Klicken Sie auf
Neu, und wählen Sie Name der Modulklasse = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenConsumeLoginModule aus.
- Klicken Sie auf
Neu, und geben Sie
Name der Modulklasse = test.tokens.MyCustomConsumer an.
- Wählen Sie
Proxy für Anmeldemodul verwenden aus.
- Klicken Sie auf OK.
- Klicken Sie auf Speichern.
- Erstellen Sie den angepassten Richtliniensatz.
- Klicken Sie in der Administrationskonsole auf Services > Richtliniensätze > Anwendungsrichtliniensätze.
- Klicken Sie auf
Neu, und geben Sie
ACustomTokenPolicy an.
- Klicken Sie auf Anwenden.
- Klicken Sie unter der Überschrift "Richtlinie" auf Hinzufügen > WS-Security.
- Bearbeiten Sie den angepassten Richtliniensatz.
- Klicken Sie in der Administrationskonsole auf WS-Security > Hauptrichtlinie.
- Entfernen Sie die unerwünschten Elemente:
- Wählen Sie Zeitmarke in Sicherheitsheader einfügen ab.
- Wählen Sie Zugriffsschutz auf Nachrichtenebene ab.
- Fügen Sie das angepasste Token hinzu.
- Klicken Sie auf
Richtlinien für Anforderungstoken.
- Klicken Sie auf
Tokentyp hinzufügen > Angepasst, und geben Sie Folgendes an:
- Name des angepassten Tokens = myToken
- Lokaler Abschnitt = MyToken
- Namespace-URI = http://www.acme.com
- Klicken Sie auf OK.
- Klicken Sie auf Speichern.
- Konfigurieren Sie den Client für die Verwendung des Richtliniensatzes
ACustomTokenPolicy.
- Klicken Sie in der Administrationskonsole auf Services > Service-Clients.
- Klicken Sie auf den gewünschten Service-Client.
- Wählen Sie die Ressource auf der höchsten Ebene aus.
- Klicken Sie auf Richtliniensatz zuordnen.
- Wählen Sie ACustomTokenPolicy aus.
- Erstellen Sie eine angepasste Bindung für den Client.
- Wählen Sie erneut die Ressource auf der höchsten Ebene aus.
- Klicken Sie auf Bindung zuweisen.
- Klicken Sie auf Neue anwendungsspezifische Bindung, um eine anwendungsspezifische
Bindung zu erstellen.
- Geben Sie den Bindungskonfigurationsnamen an.
Name:
customTokenClientBinding
- Klicken Sie auf Hinzufügen > WS-Security.
Wenn die Anzeige
"Hauptrichtlinienbindungen für Nachrichtensicherheit" nicht erscheint, wählen Sie
WS-Security aus.
- Konfigurieren Sie die angepassten Bindungen für den Client.
- Wählen Sie Authentifizierung und Zugriffsschutz > request:myToken aus.
- Wählen Sie JAAS-Anmeldung = test.generate.custom aus.
- Klicken Sie auf Anwenden.
- Klicken Sie auf Callback-Handler.
- Fügen Sie die angepasste Eigenschaft passThroughToken=true hinzu.
- Konfigurieren Sie den Provider für die Verwendung des Richtliniensatzes ACustomTokenPolicy.
- Klicken Sie in der Administrationskonsole auf Services > Service-Provider.
- Klicken Sie auf den gewünschten Service-Provider.
- Wählen Sie die Ressource auf der höchsten Ebene aus.
- Klicken Sie auf Richtliniensatz zuordnen.
- Wählen Sie ACustomTokenPolicy aus.
- Erstellen Sie eine angepasste Bindung für den Provider.
- Wählen Sie erneut die Ressource auf der höchsten Ebene aus.
- Klicken Sie auf Bindung zuweisen.
- Klicken Sie auf Neue anwendungsspezifische Bindung, um eine anwendungsspezifische
Bindung zu erstellen.
- Geben Sie den Bindungskonfigurationsnamen an.
customTokenProviderBinding
- Klicken Sie auf Hinzufügen > WS-Security.
Wenn die Anzeige
"Hauptrichtlinienbindungen für Nachrichtensicherheit" nicht erscheint, wählen Sie
WS-Security aus.
- Konfigurieren Sie die angepasste Bindungen für den Provider.
- Wählen Sie Authentifizierung und Zugriffsschutz > request:myToken aus.
- Wählen Sie JAAS-Anmeldung = test.consume.custom aus.
- Klicken Sie auf Anwenden.
- Klicken Sie auf Callback-Handler.
- Fügen Sie die angepassten Eigenschaften
passThroughToken=true und alwaysGeneric=true hinzu.
- Klicken Sie auf Speichern, um die Konfigurationsänderungen zu speichern.
- Starten Sie den Anwendungsserver erneut, um die JAAS-Konfigurationsänderungen anzuwenden.
- Testen Sie Ihren Service.
Beispiel
Im folgenden Beispiel ist der SOAP-Sicherheitsheader dargestellt, der erzeugt wird, wenn Sie die vorangegangene Prozedur ausführen.
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<acme:MyToken xmlns:acme="http://www.acme.com" xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
<acme:Email>joe.smith@acme.com</acme:Email>
</acme:MyToken>
</wsse:Security>