2012-11-18 9 views
5

Ich habe ein Mash up von ein paar Tutorials gefolgt und nicht so erfolgreich!Apache CXF und WS-Sicherheit - Passwort Rückruf

Ich versuche, Apache CXF und WS-Security zu meinem Spring Security Authenticator zurückzurufen. Alles ist in der Nähe zu arbeiten, aber im Moment habe ich ein Problem, das Passwort zu bekommen, um Spring-Sicherheit aus dem WS-Call zurück zu geben.

Der Handler unten erhält einen Fehler, aber pc.getPassword() ist null. Ich möchte dies das Passwort in Soap geschickt sein, so kann ich es passieren springen

public class ServerPasswordCallback implements CallbackHandler { 

public void handle(Callback[] callbacks) throws IOException, 
    UnsupportedCallbackException { 

    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 

    pc.setPassword(pc.getPassword()); 
} 

Mein Interceptor als eingerichtet ist so

<bean id="wsAuthenticationInterceptor" class="com.olympus.viewtheworld.server.security.auth.WSAuthenticationInInterceptor"> 
    <constructor-arg index="0"> 
     <map key-type="java.lang.String" value-type="java.lang.Object"> 
      <entry key="action" value="UsernameToken" /> 
      <entry key="passwordType" value="PasswordText" /> 
      <entry key="passwordCallbackClass" value="com.olympus.viewtheworld.server.security.auth.ServerPasswordCallback" /> 
     </map> 
    </constructor-arg> 
    <property name="authenticationManager" ref="authenticationManager"/> 
</bean> 

<jaxws:endpoint id="secureHelloService" 
       implementor="#secureHelloServiceImpl" 
       implementorClass="com.olympus.viewtheworld.server.service.Impl.SecureHelloServiceImpl" 
       address="/SoapService/secure/hello"> 
    <jaxws:serviceFactory> 
     <ref bean="jaxws-and-aegis-service-factory" /> 
    </jaxws:serviceFactory> 
    <jaxws:inInterceptors> 
     <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/> 
     <ref bean="wsAuthenticationInterceptor" /> 
    </jaxws:inInterceptors> 
</jaxws:endpoint> 

Und die Seife Anfrage ich aus SoapUI sende ist

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://test/"> 
    <soapenv:Header> 
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
<wsse:UsernameToken> 
<wsse:Username>rob2</wsse:Username> 
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passwordxx</wsse:Password> 
</wsse:UsernameToken> 
</wsse:Security> 
</soapenv:Header> 
    <soapenv:Body> 
     <test:hello> 
     <!--Optional:--> 
     <hello>asdf</hello> 
     </test:hello> 
    </soapenv:Body> 
</soapenv:Envelope> 

Version weise ist es Frühling 3.1 und CXF 2.7.0

Was muss ich tun, um zu sehen „passwordxx "in der ServerPasswordCallback-Klasse? Ist es die Soap-Anfrage, die Config oder einfach falsch ?!

Cheers, Rob

Antwort

0

Ok so dass diese nicht die ideale Lösung ist und hoffentlich eine bessere Antwort auf ein wenig später auf der ganzen Linie kommen wird, höchstwahrscheinlich, wenn ich etwas mehr Zeit, dies zu betrachten haben.

Ich benutze eine Regex, um das vollständige Paket zu untersuchen und das Passwortfeld herauszuziehen. Code ist unten. Wird später aktualisiert, wenn ich den richtigen Weg finde, dies zu tun, denn das ist definitley nicht!

WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 
     String mydata= pc.getRequestData().getMsgContext().toString();   
     Pattern pattern = Pattern.compile("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">(.*?)<"); 
     Matcher matcher = pattern.matcher(mydata); 
     if (matcher.find()) 
     { 
      pc.setPassword(matcher.group(1)); 
     } 
1

Es ergibt sich aus der Dokumentation zu org.apache.ws.security.handler.WSHandlerConstants.PW_CALLBACK_CLASS, dass das Verfahren statt pc.setPassword mit dem gespeicherten Passwort aufrufen sollte dem Benutzer angegebene Passwort gegen als Argument, statt dem Benutzer bereitgestellt Passwort selbst zu vergleichen:

Diese Tag bezieht sich auf die CallbackHandler-Implementierungsklasse, die für Kennwörter verwendet wird. Der Wert dieses Tags muss der Klassenname einer javax.security.auth.callback.CallbackHandler-Instanz sein. Die Callback-Funktion

javax.security.auth.callback.CallbackHandler.handle(javax.security.auth.callback.Callback[])

Ruft ein Array von org.apache.ws.security.WSPasswordCallback Objekten. Nur der erste Eintrag des Arrays wird verwendet. Dieses Objekt enthält den Benutzernamen/Schlüsselname als Kennung. Der Callback-Handler muss das Kennwort oder den Schlüssel, der diesem Bezeichner zugeordnet ist, vor der Rückgabe festlegen.Die Anwendung kann diesen Parameter legen Sie die folgende Methode:

call.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, "PWCallbackClass");


Ich bin ein org.apache.ws.security.validate.Validator mit der Gültigkeit des mitgelieferten Passwort zu überprüfen, und die Federsicherheitskontext Einstellung dort:

@Bean(name = "wssforjInInterceptor") 
public WSS4JInInterceptor wssforjInInterceptor() { 
    // Configure how we ask for username and password 
    Map<String, Object> props = new HashMap<>(); 
    props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); 
    props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 

    // Password callback 
    props.put(WSHandlerConstants.PW_CALLBACK_REF, passwordCallbackHandler()); 

    // Validator registration 
    Map<QName, Object> validators = new HashMap<>(); 
    String WSS_WSSECURITY_SECEXT_1_0_XSD = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 
    QName qName = new QName(WSS_WSSECURITY_SECEXT_1_0_XSD, WSHandlerConstants.USERNAME_TOKEN, ""); 
    validators.put(qName, usernameTokenValidator()); 
    props.put(WSS4JInInterceptor.VALIDATOR_MAP, validators); 

    WSS4JInInterceptor wss4jInInterceptor = new WSS4JInInterceptor(props); 
    return wss4jInInterceptor; 
} 

ich bin nicht sicher, ob dieser Ansatz besser oder schlechter (würde ich ein Feedback zu diesem Thema schätzen), aber vielleicht ist es nützlich für die nächste Person, die auf dieses Problem stößt. Es scheint einen Mangel an anständiger, aktueller Dokumentation darüber zu geben, wie Spring Security und CXF zu integrieren sind.