WebLogic 中的 JAX-WS 客户端 运行 中的 PasswordDigest 身份验证失败
PasswordDigest authentication fails in JAX-WS client running in WebLogic
我正在尝试实现一个使用 PasswordDigest 身份验证的 JAX-WS Web 服务客户端。
这是我的网络服务客户端:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.AddressingFeature;
@Stateless
public class JaxWsService {
/**
* We cache the web service client, but on a thread local variable to avoid any potential multi-threading
* issues.
*/
private ThreadLocal<MyService> threadLocalClient = new ThreadLocal<MyService>();
@WebServiceRef(wsdlLocation = "http://localhost:9999/mockMyService?WSDL")
private MyServiceInterface service;
@PostConstruct
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);
List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = ( ( BindingProvider )proxy ).getBinding();
binding.setHandlerChain(handlerChain);
threadLocalClient.set(proxy);
}
public Response doSomething(String guid) {
MyService client = threadLocalClient.get();
return client.doSomething(guid);
}
}
这是我的 SOAPHandler:
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import ca.ns.gov.sns.rmv.util.PropertyUtil;
import sun.misc.BASE64Encoder;
public class PasswordDigestHeaderHandler implements SOAPHandler<SOAPMessageContext> {
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static DateFormat headerDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String wssePrefix = "wsse";
private static final String wsseURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String wsuPrefix = "wsu";
private static final String wsuURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
try {
// Nonce
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.setSeed(System.currentTimeMillis());
byte[] nonceBytes = new byte[16];
rand.nextBytes(nonceBytes);
// Created date
headerDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance();
String createdDate = headerDateFormat.format(now.getTime());
byte[] createdDateBytes = createdDate.getBytes(ENCODING_UTF_8);
// Password
byte[] passwordBytes = PASSWORD.getBytes(ENCODING_UTF_8);
// SHA-1 hash the bunch of it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(nonceBytes);
baos.write(createdDateBytes);
baos.write(passwordBytes);
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] digestedPassword = md.digest(baos.toByteArray());
// Encode the password and nonce
String passwordB64 = (new BASE64Encoder()).encode(digestedPassword);
String nonceB64 = (new BASE64Encoder()).encode(nonceBytes);
now.add(Calendar.SECOND, 1000);
String expiresTimestamp = headerDateFormat.format(now.getTime());
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();
// Security
SOAPElement securityE = factory.createElement("Security", wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wsuPrefix, wsuURI);
securityE.addAttribute(new QName("mustUnderstand"), "1");
// Security/Timestamp
SOAPElement timestampE = factory.createElement("Timestamp", wsuPrefix, wsuURI);
timestampE.setAttributeNS(wsuURI, "wsu:Id", "TS-" + generateRandomString());
SOAPElement createdE = factory.createElement("Created", wsuPrefix, wsuURI);
createdE.addTextNode(createdDate);
timestampE.addChildElement(createdE);
SOAPElement expiresE = factory.createElement("Expires", wsuPrefix, wsuURI);
expiresE.addTextNode(expiresTimestamp);
timestampE.addChildElement(expiresE);
// Security/UsernameToken
SOAPElement usernameTokenE = factory.createElement("UsernameToken", wssePrefix, wsseURI);
usernameTokenE.setAttributeNS(wsuURI, "wsu:Id", "UsernameToken-" + generateRandomString());
SOAPElement userE = factory.createElement("Username", wssePrefix, wsseURI);
userE.addTextNode(USERNAME);
SOAPElement pwdE = factory.createElement("Password", wssePrefix, wsseURI);
pwdE.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
pwdE.addTextNode(passwordB64);
SOAPElement nonceE = factory.createElement("Nonce", wssePrefix, wsseURI);
nonceE.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceE.addTextNode(nonceB64);
usernameTokenE.addChildElement(userE);
usernameTokenE.addChildElement(pwdE);
usernameTokenE.addChildElement(nonceE);
usernameTokenE.addChildElement(createdE);
securityE.addChildElement(timestampE);
securityE.addChildElement(usernameTokenE);
SOAPHeader header = envelope.getHeader();
if (header == null){
header = envelope.addHeader();
}
header.addChildElement(securityE);
context.getMessage().saveChanges();
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}
@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName(wsseURI, "Security", wssePrefix);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}
@Override
public void close(MessageContext context) {}
@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
/**
* Generates a random string used in the Timestamp and UsernameToken elements.
*
* @return
*/
private String generateRandomString() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
...这些是由 ClientGenTask 生成的我的 Web 服务工件:
@WebServiceClient...
public class MyServiceInterface
extends Service
{
...
@WebService...
@XmlSeeAlso({
ObjectFactory.class
})
public interface MyService {
...这是网络服务的政策:
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="wss_username_token_over_ssl_service_policy_PasswordDigest">
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false">
<wsp:Policy/>
</sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>
大部分代码取自我作为概念证明编写的独立应用程序,该应用程序运行良好。我能够访问 Web 服务并获得预期的响应。
但是当我将代码迁移到 Weblogic 12.1.3 中的 运行 时,我开始收到此错误:
Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Unable to add security token for identity, token uri =http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken
是否需要通过 WebLogic 控制台完成一些设置才能从客户端启用 PasswordDigest,或者我是否遗漏了代码中的某些内容?
这是完整的堆栈跟踪:
Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Unable to add security token for identity, token uri =http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:131)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy367.retrieveDocumentRequest(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:87)
at com.sun.proxy.$Proxy365.retrieveDocumentRequest(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService.retrieveDocument(MyServiceSOAJaxWsService.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy358.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:33)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyServiceBean.retrieveDocument(MyServiceBean.java:347)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy353.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.retrieveDocument(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:84)
at com.sun.proxy.$Proxy151.retrieveDocument(Unknown Source)
at com.myclient.project.web.ods.ODSRenderAttachment.init(ODSRenderAttachment.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokeAnnotatedMethod(WebContainerInjectionProvider.java:113)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokePostConstruct(WebContainerInjectionProvider.java:95)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:408)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:268)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1785)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.myclient.project.util.faces.CustomViewHandler.renderView(CustomViewHandler.java:63)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:604)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:54)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.PersistenceFilter.doFilter(PersistenceFilter.java:86)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.UploadFilter.doFilter(UploadFilter.java:83)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.ClientTransactionConversationFilter.doFilter(ClientTransactionConversationFilter.java:34)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
奇怪的是,如果我通过 PasswordDigestHeaderHandler(如下)获取 XML 即 generated/output 并将其粘贴到 SoapUI 中,请求就可以工作。这似乎暗示缺少某些 WebLogic 配置。
<S:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-6b8a287b7bf641f19b6841d555e9f380">
<wsu:Created>2018-11-13T18:11:53.541Z</wsu:Created>
<wsu:Expires>2018-11-13T18:28:33.541Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-183099de358f4f0685eb34783a8b1c5c">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">42Nl15QHYJymbpxFDFC5kccoWuk=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9NTLR/h+GQQwRd1fQRxnqg==</wsse:Nonce>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-13T18:11:53.541Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<S:Body>
<RetrieveDocumentRequest
xmlns="http://mycompany.com/MyService">
...
</RetrieveDocumentRequest>
</S:Body>
</S:Envelope>
尝试使用您的 init()
方法,您可能需要添加 WebLogic
凭证提供程序:
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);
List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());
BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);
// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));
Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate[] chain, int validateErr) {
return true;
}
}
);
threadLocalClient.set(proxy);
}
试试这个。
- 下载描述您的服务的 WSDL 文件并通过注释掉定义 wsp:PolicyReference: 的行来修改它。
将它放在一个文件夹中,该文件夹将包含在您的 jar/war/ear 文件中(例如 META-INF/wsdl)。
在您的 Web 服务客户端中,更改您的 @WebServiceRef 注入以引用此 local/bundled 版本的 WSDL:
@WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl")
private MyServiceInterface service;
将您的客户端初始化代码修改为如下所示:
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);
BindingProvider bindingProvider = (BindingProvider) proxy;
List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);
// Add these two lines, to point to the remote service
Map<String, Object> context = bindingProvider.getRequestContext();
context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT);
threadLocalClient.set(proxy);
... 其中 REMOTE_SERVICE_ENDPOINT 是您正在访问的远程 Web 服务的 URL。
应该可以了。您不必修改 PasswordDigestHeaderHandler 实现。
我在完全相同的问题上花了相当多的时间,但这个帖子让我走上了正确的道路:https://community.oracle.com/thread/2485783。
祝你好运。
我正在尝试实现一个使用 PasswordDigest 身份验证的 JAX-WS Web 服务客户端。
这是我的网络服务客户端:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.AddressingFeature;
@Stateless
public class JaxWsService {
/**
* We cache the web service client, but on a thread local variable to avoid any potential multi-threading
* issues.
*/
private ThreadLocal<MyService> threadLocalClient = new ThreadLocal<MyService>();
@WebServiceRef(wsdlLocation = "http://localhost:9999/mockMyService?WSDL")
private MyServiceInterface service;
@PostConstruct
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);
List<Handler> handlerChain = new ArrayList<Handler>();
//Add a handler to the handler chain
handlerChain.add( new PasswordDigestHeaderHandler() );
Binding binding = ( ( BindingProvider )proxy ).getBinding();
binding.setHandlerChain(handlerChain);
threadLocalClient.set(proxy);
}
public Response doSomething(String guid) {
MyService client = threadLocalClient.get();
return client.doSomething(guid);
}
}
这是我的 SOAPHandler:
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import ca.ns.gov.sns.rmv.util.PropertyUtil;
import sun.misc.BASE64Encoder;
public class PasswordDigestHeaderHandler implements SOAPHandler<SOAPMessageContext> {
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static DateFormat headerDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String wssePrefix = "wsse";
private static final String wsseURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String wsuPrefix = "wsu";
private static final String wsuURI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
@Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
try {
// Nonce
SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
rand.setSeed(System.currentTimeMillis());
byte[] nonceBytes = new byte[16];
rand.nextBytes(nonceBytes);
// Created date
headerDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance();
String createdDate = headerDateFormat.format(now.getTime());
byte[] createdDateBytes = createdDate.getBytes(ENCODING_UTF_8);
// Password
byte[] passwordBytes = PASSWORD.getBytes(ENCODING_UTF_8);
// SHA-1 hash the bunch of it.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(nonceBytes);
baos.write(createdDateBytes);
baos.write(passwordBytes);
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] digestedPassword = md.digest(baos.toByteArray());
// Encode the password and nonce
String passwordB64 = (new BASE64Encoder()).encode(digestedPassword);
String nonceB64 = (new BASE64Encoder()).encode(nonceBytes);
now.add(Calendar.SECOND, 1000);
String expiresTimestamp = headerDateFormat.format(now.getTime());
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();
// Security
SOAPElement securityE = factory.createElement("Security", wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wssePrefix, wsseURI);
securityE.addNamespaceDeclaration(wsuPrefix, wsuURI);
securityE.addAttribute(new QName("mustUnderstand"), "1");
// Security/Timestamp
SOAPElement timestampE = factory.createElement("Timestamp", wsuPrefix, wsuURI);
timestampE.setAttributeNS(wsuURI, "wsu:Id", "TS-" + generateRandomString());
SOAPElement createdE = factory.createElement("Created", wsuPrefix, wsuURI);
createdE.addTextNode(createdDate);
timestampE.addChildElement(createdE);
SOAPElement expiresE = factory.createElement("Expires", wsuPrefix, wsuURI);
expiresE.addTextNode(expiresTimestamp);
timestampE.addChildElement(expiresE);
// Security/UsernameToken
SOAPElement usernameTokenE = factory.createElement("UsernameToken", wssePrefix, wsseURI);
usernameTokenE.setAttributeNS(wsuURI, "wsu:Id", "UsernameToken-" + generateRandomString());
SOAPElement userE = factory.createElement("Username", wssePrefix, wsseURI);
userE.addTextNode(USERNAME);
SOAPElement pwdE = factory.createElement("Password", wssePrefix, wsseURI);
pwdE.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
pwdE.addTextNode(passwordB64);
SOAPElement nonceE = factory.createElement("Nonce", wssePrefix, wsseURI);
nonceE.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceE.addTextNode(nonceB64);
usernameTokenE.addChildElement(userE);
usernameTokenE.addChildElement(pwdE);
usernameTokenE.addChildElement(nonceE);
usernameTokenE.addChildElement(createdE);
securityE.addChildElement(timestampE);
securityE.addChildElement(usernameTokenE);
SOAPHeader header = envelope.getHeader();
if (header == null){
header = envelope.addHeader();
}
header.addChildElement(securityE);
context.getMessage().saveChanges();
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}
@Override
public Set<QName> getHeaders() {
QName securityHeader = new QName(wsseURI, "Security", wssePrefix);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}
@Override
public void close(MessageContext context) {}
@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
/**
* Generates a random string used in the Timestamp and UsernameToken elements.
*
* @return
*/
private String generateRandomString() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
...这些是由 ClientGenTask 生成的我的 Web 服务工件:
@WebServiceClient...
public class MyServiceInterface
extends Service
{
...
@WebService...
@XmlSeeAlso({
ObjectFactory.class
})
public interface MyService {
...这是网络服务的政策:
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="wss_username_token_over_ssl_service_policy_PasswordDigest">
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false">
<wsp:Policy/>
</sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:Policy>
大部分代码取自我作为概念证明编写的独立应用程序,该应用程序运行良好。我能够访问 Web 服务并获得预期的响应。
但是当我将代码迁移到 Weblogic 12.1.3 中的 运行 时,我开始收到此错误:
Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Unable to add security token for identity, token uri =http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken
是否需要通过 WebLogic 控制台完成一些设置才能从客户端启用 PasswordDigest,或者我是否遗漏了代码中的某些内容?
这是完整的堆栈跟踪:
Caused By: com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Unable to add security token for identity, token uri =http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:193)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:131)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:92)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:161)
at com.sun.proxy.$Proxy367.retrieveDocumentRequest(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:87)
at com.sun.proxy.$Proxy365.retrieveDocumentRequest(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService.retrieveDocument(MyServiceSOAJaxWsService.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy358.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:33)
at com.myclient.project.services.ods.myservice.MyServiceSOAJaxWsService_elmy9k_myserviceServiceImpl.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyServiceBean.retrieveDocument(MyServiceBean.java:347)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at com.oracle.pitchfork.intercept.MethodInvocationInvocationContext.proceed(MethodInvocationInvocationContext.java:100)
at com.myclient.project.audit.AuditInterceptor.aroundInvoke(AuditInterceptor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.oracle.pitchfork.intercept.JeeInterceptorInterceptor.invoke(JeeInterceptorInterceptor.java:109)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(Unknown Source)
at com.sun.proxy.$Proxy353.retrieveDocument(Unknown Source)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.myclient.project.services.ods.MyService_tev81c_MyServiceImpl.retrieveDocument(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:84)
at com.sun.proxy.$Proxy151.retrieveDocument(Unknown Source)
at com.myclient.project.web.ods.ODSRenderAttachment.init(ODSRenderAttachment.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokeAnnotatedMethod(WebContainerInjectionProvider.java:113)
at com.sun.faces.vendor.WebContainerInjectionProvider.invokePostConstruct(WebContainerInjectionProvider.java:95)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:223)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:408)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:268)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:877)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1785)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1781)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.myclient.project.util.faces.CustomViewHandler.renderView(CustomViewHandler.java:63)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:604)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:346)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:54)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.PersistenceFilter.doFilter(PersistenceFilter.java:86)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.UploadFilter.doFilter(UploadFilter.java:83)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at com.myclient.project.util.ClientTransactionConversationFilter.doFilter(ClientTransactionConversationFilter.java:34)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:79)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3436)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3402)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2285)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2201)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1572)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:255)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
奇怪的是,如果我通过 PasswordDigestHeaderHandler(如下)获取 XML 即 generated/output 并将其粘贴到 SoapUI 中,请求就可以工作。这似乎暗示缺少某些 WebLogic 配置。
<S:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-6b8a287b7bf641f19b6841d555e9f380">
<wsu:Created>2018-11-13T18:11:53.541Z</wsu:Created>
<wsu:Expires>2018-11-13T18:28:33.541Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-183099de358f4f0685eb34783a8b1c5c">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">42Nl15QHYJymbpxFDFC5kccoWuk=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9NTLR/h+GQQwRd1fQRxnqg==</wsse:Nonce>
<wsu:Created
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2018-11-13T18:11:53.541Z
</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<S:Body>
<RetrieveDocumentRequest
xmlns="http://mycompany.com/MyService">
...
</RetrieveDocumentRequest>
</S:Body>
</S:Envelope>
尝试使用您的 init()
方法,您可能需要添加 WebLogic
凭证提供程序:
private void init() {
AddressingFeature feature = new AddressingFeature(true, false);
MyService proxy = service.getMyService(feature);
List<Handler> handlerChain = new ArrayList<>();
// Add a handler to the handler chain
handlerChain.add(new PasswordDigestHeaderHandler());
BindingProvider bindingProvider = (BindingProvider) proxy;
Binding binding = bindingProvider.getBinding();
binding.setHandlerChain(handlerChain);
// weblogic.xml.crypto.wss.provider.CredentialProvider
// weblogic.wsee.security.unt.ClientUNTCredentialProvider
List<CredentialProvider> credProviders = new ArrayList<>();
credProviders.add(new ClientUNTCredentialProvider(USERNAME.getBytes(), PASSWORD.getBytes()));
Map<String, Object> context = bindingProvider.getRequestContext();
// weblogic.xml.crypto.wss.WSSecurityContext
context.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credProviders);
// weblogic.security.SSL.TrustManager
context.put(
WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate[] chain, int validateErr) {
return true;
}
}
);
threadLocalClient.set(proxy);
}
试试这个。
- 下载描述您的服务的 WSDL 文件并通过注释掉定义 wsp:PolicyReference: 的行来修改它。
将它放在一个文件夹中,该文件夹将包含在您的 jar/war/ear 文件中(例如 META-INF/wsdl)。
在您的 Web 服务客户端中,更改您的 @WebServiceRef 注入以引用此 local/bundled 版本的 WSDL:
@WebServiceRef(wsdlLocation = "META-INF/wsdl/MyService.wsdl") private MyServiceInterface service;
将您的客户端初始化代码修改为如下所示:
AddressingFeature feature = new AddressingFeature(true, false); MyService proxy = service.getMyService(feature); BindingProvider bindingProvider = (BindingProvider) proxy; List<Handler> handlerChain = new ArrayList<Handler>(); //Add a handler to the handler chain handlerChain.add( new PasswordDigestHeaderHandler() ); Binding binding = bindingProvider.getBinding(); binding.setHandlerChain(handlerChain); // Add these two lines, to point to the remote service Map<String, Object> context = bindingProvider.getRequestContext(); context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, REMOTE_SERVICE_ENDPOINT); threadLocalClient.set(proxy);
... 其中 REMOTE_SERVICE_ENDPOINT 是您正在访问的远程 Web 服务的 URL。
应该可以了。您不必修改 PasswordDigestHeaderHandler 实现。
我在完全相同的问题上花了相当多的时间,但这个帖子让我走上了正确的道路:https://community.oracle.com/thread/2485783。
祝你好运。