2011-07-09 7 views
6

クライアントを.net soap Webサービスに作成していますが、パスワードを正しく渡す方法がわかりません。ここに私の「ハードコーディングされた」パスワードの例です:CXFクライアントセキュリティ

@Test 
public void exploratorySecurityTest() { 
    String username = "user"; 
    String password = "pwd"; 

    UserStoryService service = new UserStoryService(); 
    UserStoryServiceSoap port = service.getUserStoryServiceSoap(); 

    //initialize security 
    org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port); 
    org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 
    Map<String, Object> outProps = new HashMap<String, Object>(); 
    outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); 
    outProps.put(WSHandlerConstants.USER, username); 
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 
    outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName()); 
    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 
    cxfEndpoint.getOutInterceptors().add(wssOut); 

    int storyId = 33401; 
    UserStoryDTO userStoryDTO = port.getByID(storyId); 

    //success if no error 
} 

public class ClientPasswordCallback implements CallbackHandler { 

@Override 
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { 
    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 
    pc.setPassword("pwd"); 
} 

}

私が本当にやりたいことはコールバックハンドラにパスワードを渡すことです。私はCXFドキュメントで見てきた例は、いずれかの「ハードコードされた」(私はこの例で行ったように)、またはユーザ名の関数としてコールバックを実装します。

if (pc.getIdentifier().equals("user")) { 
    pc.setPassword("pwd"); 
} 

これらのどちらもが、私のニーズを満たしています。代わりに

@Test 
public void exploratorySecurityTest() { 
    String username = "user"; 
    String password = "pwd"; 

    UserStoryService service = new UserStoryService(); 
    UserStoryServiceSoap port = service.getUserStoryServiceSoap(); 

    //initialize security 
    org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port); 
    org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 
    Map<String, Object> outProps = new HashMap<String, Object>(); 
    outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); 
    outProps.put(WSHandlerConstants.USER, username); 

      //pass the password here? 
      outProps.put("password", password); 

    outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 
    outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientPasswordCallback.class.getName()); 
    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 

    cxfEndpoint.getOutInterceptors().add(wssOut); 
      ... 
} 
+0

ところで:私は[http://stackoverflow.com/questions/5906154/apache-cxf-credentials-not-being-sent-from-wss4joutinterceptor]の方法がここにレイアウトしようとしましたが、運 – jayraynet

答えて

9

使用PW_CALLBACK_REF PW_CALLBACK_CLASS、代わりに静的クラスで、インスタンス化されたオブジェクトを渡す:私は、次のような何かを行うことができます方法はあります。あなたは、そのオブジェクトにパスワードを注入することができます。

ような何か:私はまた、次の操作を行うことができました

outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 
    CXFClientPasswordHandler handler = new CXFClientPasswordHandler(); 
    handler.setPassword(password); 
    outProps.put(WSHandlerConstants.PW_CALLBACK_REF, handler); 
3

org.apache.cxf.endpoint.Client client = ClientProxy.getClient(obj); 
    org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 

    Map<String, Object> outProps = new HashMap<String, Object>(); 

    outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN); 

    System.out.println("initialize security for user " + this.username); 
    outProps.put(WSHandlerConstants.USER, this.username); 
    outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 

    Map<String, Object> ctx = ((BindingProvider) obj).getRequestContext(); 
    ctx.put("password", this.password); 

    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 
    cxfEndpoint.getOutInterceptors().add(wssOut); 
+0

ハンドラーの内部から「パスワード」パラメーターにアクセスするにはどうすればよいですか?この場合、カスタムハンドラを定義する必要はありませんか? –

0

私は追加するためのHTTPレベルの認証とのCallbackHandlerのためのコンテキストを要求するためにプロパティを追加する次のような方法を常にを使用していますメッセージレベルのユーザー名トークン。

org.apache.cxf.endpoint.Client client = ClientProxy.getClient(obj); 
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); 


System.out.println("initialize security for user " + this.username); 
outProps.put(WSHandlerConstants.USER, this.username); 
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); 

Map<String, Object> requestContext = ((BindingProvider) obj).getRequestContext(); 


//For message level authentication 
requestContext.put("ws-security.username", "Ron"); 
requestContext.put("ws-security.callback-handler", "com.ws.cxf.client.callback.UTPasswordCallback"); 

//For endpoint level authentication, HTTP Basic/Digest 
requestContext.put(BindingProvider.USERNAME_PROPERTY, username); 
requestContext.put(BindingProvider.PASSWORD_PROPERTY, password); 




class UTPasswordCallback implements CallbackHandler { 

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


    for(Callback cb:callbacks){ 
     WSPasswordCallback pcallback = (WSPasswordCallback)cb; 
     if(pcallback.getUsage()==WSPasswordCallback.USERNAME_TOKEN) 
     { 

      if(pcallback.getIdentifier().equals("Ron")) 
       pcallback.setPassword("noR"); 

     } 

     } 


    } 

}