Apache CXF - учетные данные не отправляются с WSS4JOutInterceptor? - PullRequest
9 голосов
/ 06 мая 2011

Я пытаюсь подключиться к веб-службе, используя WS-Security UsernameToken spec 1.0, используя apache cxf 2.4.0.

Я скопировал приведенный ниже код из документации CXF, но получаю: org.apache.cxf.ws.policy.PolicyException: имя пользователя недоступно

    MyService_Service ss = new MyService_Service(wsdlURL, SERVICE_NAME);
    MyService port = ss.getBasicHttpBindingMyService ();  


    Client client = ClientProxy.getClient(port);
    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, 
    ClientPasswordHandler.class.getName());

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

Я также реализовал класс ClientPasswordHandler, опять же из документов, но кажется, что имя пользователя никогда не отправляется (в соответствии сошибка).Вот обработчик пароля:

public class ClientPasswordHandler implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
    pc.setPassword("Password");     
    }
}

Есть ли способ узнать, применяется ли WSS4Jinterceptor и отправлено ли имя пользователя Token?

Ответы [ 3 ]

19 голосов
/ 06 мая 2011

Получаете ли вы PolicyException на стороне клиента?Если это так, это, вероятно, означает, что используемый вами WSDL содержит фрагмент WS-SecucurityPolicy, который описывает политику UsernameToken, которую он хочет и ожидает.Если это так, то вам вообще не следует настраивать WSS4JOutInterceptor.Среда выполнения WS-Policy с этим справится, и вам просто нужно предоставить некоторые свойства, которые могут ей понадобиться.

Документы для SecurityPolicy находятся по адресу: http://cxf.apache.org/docs/ws-securitypolicy.html

Вы, вероятно,просто нужно использовать:


Map ctx = ((BindingProvider)port).getRequestContext();
ctx.put("ws-security.username", "USERNAME");
ctx.put("ws-security.password", "Password");
1 голос
/ 16 февраля 2018

Благодаря Дэниелу полная рабочая конфигурация для меня следующая:

    webServicePort = webService_service.getPort(WebService.class);

    Client client = ClientProxy.getClient(webServicePort);

    Endpoint cxfEndpoint = client.getEndpoint();

    Map<String, Object> props = ((BindingProvider) webServicePort).getRequestContext();
    props.put("ws-security.username", PravoRuConstants.USERNAME);
    props.put("ws-security.password", PravoRuConstants.PASSWORD);

    props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    props.put(WSHandlerConstants.USER, PravoRuConstants.USERNAME);
    props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);

    props.put(WSHandlerConstants.PW_CALLBACK_CLASS, PravoRuPasswordHandler.class.getName());

    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);
    cxfEndpoint.getOutInterceptors().add(wssOut);
1 голос
/ 21 апреля 2015

При использовании ответа от Даниэля я получил следующее исключение

Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '401: Unauthorized' when communicating with http://..
at .apache.cxf.inorg.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1555)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1494)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1402)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:649)
at orgterceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:535)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:465)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:368)

Я использовал приведенное ниже, и оно заработало

Map ctx = ((BindingProvider) ssPort).getRequestContext();
        ctx.put(BindingProvider.USERNAME_PROPERTY, "user");
        ctx.put(BindingProvider.PASSWORD_PROPERTY, "pass");
        ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://c
...