2012-11-18 31 views
5

Tôi đã theo dõi một số hướng dẫn và không thành công lắm!Apache CXF và WS-Security - Gọi lại mật khẩu

Tôi đang cố gắng nhận Apache CXF và WS-Security để gọi lại cho người xác thực bảo mật mùa xuân của mình. Tất cả là gần để làm việc nhưng tại thời điểm tne tôi có một vấn đề nhận được mật khẩu để cung cấp cho an ninh mùa xuân ra khỏi WS-gọi lại.

Trình xử lý bên dưới bị tiết lộ nhưng pc.getPassword() là rỗng. Tôi muốn đây là mật khẩu được gửi trong xà phòng để tôi có thể vượt qua nó để mùa xuân

public class ServerPasswordCallback implements CallbackHandler { 

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

    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 

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

đánh chặn của tôi được thiết lập như vậy

<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> 

Và yêu cầu xà phòng tôi đang gửi ra khỏi soapUI là

<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 khôn ngoan nó là mùa xuân 3.1 và CXF 2.7.0

gì tôi cần phải làm gì để xem "passwordxx "trong lớp ServerPasswordCallback? Có phải là yêu cầu Soap, cấu hình hay sai?

Chúc mừng, Rob

Trả lời

0

Ok vì vậy đây không phải là giải pháp lý tưởng và hy vọng một câu trả lời tốt hơn sẽ đến cùng một chút sau đó xuống dòng, nhiều khả năng khi tôi có một thời gian nữa để xem xét điều này.

Tôi sử dụng regex để kiểm tra gói đầy đủ và rút ra trường mật khẩu. Mã dưới đây. Sẽ cập nhật sau khi tôi làm việc đúng cách để làm điều này vì đây là defintley phải không!

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

Nó xuất hiện từ các tài liệu trên org.apache.ws.security.handler.WSHandlerConstants.PW_CALLBACK_CLASS rằng phương pháp này thay vì nên gọi pc.setPassword với mật khẩu được lưu trữ để so sánh người dùng cung cấp mật khẩu chống lại như là đối số, thay vì người dùng cung cấp mật khẩu riêng của mình:

này thẻ đề cập đến lớp triển khai CallbackHandler được sử dụng để lấy mật khẩu. Giá trị của thẻ này phải là tên lớp của một phiên bản javax.security.auth.callback.CallbackHandler. Các hàm callback

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

được một mảng các đối tượng org.apache.ws.security.WSPasswordCallback. Chỉ mục nhập đầu tiên của mảng được sử dụng. Đối tượng này chứa tên người dùng/tên khóa làm số nhận dạng. Trình xử lý gọi lại phải đặt mật khẩu hoặc khóa được liên kết với số nhận dạng này trước khi nó trả về.Việc áp dụng có thể thiết lập thông số này bằng cách sử dụng phương pháp sau đây:

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


Tôi đang sử dụng một org.apache.ws.security.validate.Validator để kiểm tra tính hợp lệ của các mật khẩu được cung cấp, và thiết lập các bối cảnh an ninh mùa xuân có:

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

Tôi không chắc liệu cách tiếp cận đó tốt hơn hay tệ hơn (tôi đánh giá cao một số phản hồi về điều này), nhưng có lẽ nó hữu ích cho người tiếp theo gặp vấn đề này. Dường như thiếu tài liệu cập nhật về cách tích hợp bảo mật Spring và CXF.

Các vấn đề liên quan