2013-04-15 24 views
6

Używam Apache CXF do zbudowania usługi sieciowej. Używa Apache WSS4J, aby zapewnić funkcjonalność WS-Security. Muszę wysłać żądanie SOAP i musi ono zostać podpisane.Jak WSS4J załadować hasło magazynu kluczy z wywołania zwrotnego?

To jest zawartość pliku właściwości przekazać do WSS4J:

org.apache.ws.security.crypto.provider = org.apache.ws.security.components.crypto.Merlin 
org.apache.ws.security.crypto.merlin.keystore.type = PKCS12 
org.apache.ws.security.crypto.merlin.keystore.provider = BC 
org.apache.ws.security.crypto.merlin.keystore.password = 12345678 
org.apache.ws.security.crypto.merlin.keystore.alias = my-alias 
org.apache.ws.security.crypto.merlin.keystore.file = my_certificate.p12 

Chcę, aby pozbyć się tej linii z moje hasło pisał jako zwykły tekst. Usunąłem tę linię i pod hasłem obsługi wywołania zwrotnego do mojego WSS4JOutInterceptor, jak w powyższym kodzie:

public SoapInterceptor newSignerInterceptor() { 
    Map<String, Object> outProps = new HashMap<String, Object>(); 
    outProps.put(WSHandlerConstants.ACTION, "Signature"); 
    outProps.put(WSHandlerConstants.USER, config.getKeyAlias()); 
    outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference"); 
    outProps.put(WSHandlerConstants.USE_REQ_SIG_CERT, WSHandlerConstants.SIGNATURE_USER); 
    outProps.put(WSHandlerConstants.USE_SINGLE_CERTIFICATE, "false"); 
    outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, this.getClass().getName()); 
    outProps.put(WSHandlerConstants.SIG_PROP_FILE, config.getPropertiesFileName()); 
    return new WSS4JOutInterceptor(outProps); 

} 

@Override 
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
    for (int i = 0; i < callbacks.length; i++) { 
     if (callbacks[i] instanceof WSPasswordCallback) { 
      ((WSPasswordCallback) callbacks[i]).setPassword(password); 
     } 
    } 
} 

Ale to nie działa. Nie znajduje hasła w pliku właściwości i używa domyślnego hasła "security".

Jak sprawić, by korzystał z oddzwonienia, aby uzyskać hasło?

Odpowiedz

5

można zaimplementować CallbackHandler:

public class PasswordCallbackHandler implements CallbackHandler { 

    @Override 
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
     for(Callback callBack:callbacks){ 
      if(callBack instanceof WSPasswordCallback){ 
       ((WSPasswordCallback)callBack).setPassword("password"); 
      } 
     } 
    } 
} 

następnie dodać do obsługi właściwości:

outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class); 

można również użyć PW_CALLBACK_REF ustawić odniesienie do obsługi.

-1

Merlin nie wywołuje wywołania zwrotnego dla hasła magazynu kluczy, dlatego hasło zawsze musi znajdować się w pliku właściwości. Na szczęście może być zaszyfrowane.

Rozwiązanie opisane jest ładnie tutaj: Encrypting passwords in Crypto property files

Skopiowane rozwiązanie z linku powyżej:

  1. Pobierz jasypt-1.9.2-dist.zip
  2. Get zakodowane hasło z tego polecenie encrypt input=real_keystore_password password=master_password algorithm=PBEWithMD5AndTripleDES
  3. Skopiuj WYJŚCIE (przykład: 0laAaRahTQJzlsDu771tYi)
  4. Podczas korzystania z tego algorytmu m, potrzebujesz rozszerzenia Java Cryptography Extension (JCE) Unlimited Strength. Wprowadź swój JDK.
  5. Put zakodowanego wyjścia we właściwościach

    org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin 
    
    org.apache.wss4j.crypto.merlin.keystore.type=jks 
    org.apache.wss4j.crypto.merlin.keystore.password=ENC(0laAaRahTQJzlsDu771tYi) 
    
    org.apache.wss4j.crypto.merlin.keystore.alias=my_alias 
    org.apache.wss4j.crypto.merlin.keystore.file=/etc/cert/my_keystore.jks 
    
  6. W CallbackHandler, umieścić master_password wich użyty do wygenerowała kodowany jednym:

    public class WsPasswordHandler implements CallbackHandler { 
    @Override 
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
    
        for (Callback callback: callbacks){ 
         WSPasswordCallback pwdCallback= (WSPasswordCallback) callback; 
         final int usage =pwdCallback.getUsage(); 
         if (usage == WSPasswordCallback.SIGNATURE || usage==WSPasswordCallback.DECRYPT) { 
         pwdCallback.setPassword("parKeyPassword"); 
        } 
        if (usage==WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD){ 
         pwdCallback.setPassword("master_password"); 
        } 
        }   
    } 
    

    }