2013-04-15 27 views
6

Sto usando Apache CXF per creare un servizio Web. Utilizza Apache WSS4J per fornire funzionalità WS-Security. Devo fare una richiesta SOAP e deve essere firmata.Come rendere WSS4J caricare la password del keystore da un callback?

Questo è il contenuto del file properties passo a 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 

voglio sbarazzarsi di quella linea con la password ha scritto come testo normale. Ho tolto quella linea e fornito un gestore di callback password per il mio WSS4JOutInterceptor, come nel codice qui sopra:

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); 
     } 
    } 
} 

Ma che non ha funzionato. Non trova la password nel file delle proprietà e utilizza una password predefinita, "sicurezza".

Come utilizzare una richiamata per ottenere la password?

risposta

5

è possibile implementare un 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"); 
      } 
     } 
    } 
} 

quindi aggiungere il gestore per le proprietà:

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

è anche possibile utilizzare PW_CALLBACK_REF per impostare un punto di riferimento del gestore.

-1

Merlin non richiama la richiamata per la password del keystore, quindi la password deve sempre trovarsi nel file delle proprietà. Fortunatamente può essere crittografato.

La soluzione è descritta bene qui: Encrypting passwords in Crypto property files

soluzione Copiato dal link qui sopra:

  1. Scarica il jasypt-1.9.2-dist.zip
  2. ottenere una password codificati con questo comando encrypt input=real_keystore_password password=master_password algorithm=PBEWithMD5AndTripleDES
  3. Copia l'OUTPUT (Esempio: 0laAaRahTQJzlsDu771tYi)
  4. Come stai usando questo algoritmo m, hai bisogno della Java Cryptography Extension (JCE) Forza illimitata. Inserisci il tuo JDK.
  5. Mettere l'uscita codificata nelle proprietà

    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. Nel CallbackHandler, mettere il master_password wich utilizzato per generato il codificato uno:

    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"); 
        } 
        }   
    } 
    

    }