Getting "Policy alternatives can not be satisfied" from cxf enpoint - kotlin

I created a web service with cxf and camel from wsdl. Below are my bean configs:
#Bean
open fun cxfServlet(): ServletRegistrationBean<CXFServlet> {
val servlet = ServletRegistrationBean(CXFServlet(), "/ws/*")
servlet.setLoadOnStartup(1)
servlet.setName("cxfServlet")
return servlet
}
#Bean
open fun cxf(): Bus {
return BusFactory.newInstance().createBus()
}
#Bean("endpoint")
open fun endpoint(bus: Bus): CxfEndpoint {
val endpoint = CxfEndpoint()
endpoint.address = "/endpoint"
endpoint.serviceClass = IWebService::class.java
endpoint.wsdlURL = "wsdl/mywsdl.wsdl"
endpoint.dataFormat = DataFormat.POJO
endpoint.bindingId = SOAPBinding.SOAP11HTTP_BINDING
endpoint.isLoggingFeatureEnabled = true
endpoint.loggingSizeLimit = -1
return endpoint
}
Also I configured ssl. I use springBoot and my properties file is:
server.port=8442
security.require-ssl=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=123456
server.ssl.key-alias=testalias
Service's wsdl is available at the address:
https://localhost:8442/ws/endpoint?wsdl
It worked fine until the moment I used WSDl with block "Policy":
<wsp:Policy wsu:Id="id">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
</wsp:Policy>
</sp:TransportBinding>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
And now the app runs correct, but when I send message an exception appears:
org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied:
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}TransportToken
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}HttpsToken
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}AlgorithmSuite
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Basic256
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Layout
{http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Strict
But if I create server in soapUI it works fine.
I tried some advices about creating interceptors and other from stackoverflow but nothing changed.
How can I solve the problem?

Is your Webservice secured with SSL? The error complains that the declared security policy in the WSDL is not fulfilled.
Notice that the WSDL policy assertions do not set up the HTTPS transport between the requestor and provider! They ensure only that the declared mechanisms are in place when the web service with the defined policy is called.
And for SoapUI I don't really know but I assume that it ignores the policy.

Actually, I found some kind of solution with using of IgnorablePolicyInterceptorProvider. But this is just ignoring the policies, as far as I understand it, and I don't think this is a real solution:
val reg = bus.getExtension(PolicyInterceptorProviderRegistry::class.java)
val set = HashSet<QName>()
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "TransportBinding"))
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "TransportToken"))
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "HttpsToken"))
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "AlgorithmSuite"))
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "Basic256"))
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "Layout"))
set.add(QName("http://schemas.xmlsoap.org/ws/2005/07/securitypolicy", "Strict"))
reg.register(IgnorablePolicyInterceptorProvider(set))

Related

Exception while running STS Client from WSO2 Identity Server

I am new to WebServer Security and STS. I need to secure web services. My first target is to get the samples running.
As such I downloaded the STS-CLIENT from
svn co http://svn.wso2.org/repos/wso2/carbon/platform/branches/turing/products/is/5.0.0/modules/samples/sts/
as given in : https://docs.wso2.com/display/IS500/Running+an+STS+Client
I can get the token from Identity Server. Then I try to invoke a 'echoString' service hosted in Tomcat.
But in tomcat , I get the following exception :
[ERROR] General security error (WSSecurityEngine: No crypto property file supplied for decryption)
org.apache.axis2.AxisFault: General security error (WSSecurityEngine: No crypto property file supplied for decryption)
at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(RampartReceiver.java:180)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:95)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:262)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:168)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
Any help will be appreciated a lot.
<?xml version="1.0" encoding="UTF-8"?>
<service name="sample05">
<operation name="echoString">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</operation>
<parameter name="ServiceClass" locked="false">org.apache.rampart.samples.policy.sample05.SimpleService</parameter>
<module ref="rampart" />
<module ref="addressing" />
<wsp:Policy wsu:Id="SgnEncrAnonymous" 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">
<wsp:ExactlyOne>
<wsp:All>
<sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
<wsp:Policy>
<sp:RequireThumbprintReference/>
<sp:WssX509V3Token10/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:ProtectionToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Lax/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:SymmetricBinding>
<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:IssuedToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<sp:Issuer>
<Address xmlns="http://www.w3.org/2005/08/addressing">https://localhost:9443/services/wso2carbon-sts</Address>
</sp:Issuer>
<sp:RequestSecurityTokenTemplate>
<t:TokenType xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">urn:oasis:names:tc:SAML:2.0:assertion</t:TokenType>
<t:KeyType xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">http://schemas.xmlsoap.org/ws/2005/02/trust/Bearer</t:KeyType>
<t:KeySize xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">256</t:KeySize>
<t:Claims Dialect="http://wso2.org/claims"
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"
xmlns:ic="http://schemas.xmlsoap.org/ws/2005/05/identity">
<ic:ClaimType Uri="http://wso2.org/claims/givenname"/>
<ic:ClaimType Uri="http://wso2.org/claims/emailaddress"/>
</t:Claims>
</sp:RequestSecurityTokenTemplate>
<wsp:Policy>
<sp:RequireInternalReference/>
</wsp:Policy>
</sp:IssuedToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</service>

Axis2 and Rampart error

Hi I'm getting error when trying to view the available services on Axis2.
I basically need client to always send username/password to Axis2 server. Below is what I have installed:
Java7
Apache Tomcat 7.0.22
Axis2 1.6
Rampart 1.6
Tomcat starts ok. I'm able to see the Axis2 but when I click on the Services link I see below error. Below is also policy section I'm adding to services.xml. Do I have to also create a java data store JKS for certificate? Is this required? I'm just trying to get this up and running. Once this is working I will add addition security like HTTPS.
Thanks in advance.
<!-- Server policy for Username Token with plaintext password -->
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
</wsp:Policy>
</sp:TransportBinding>
<sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/wssx/ws-securitypolicy/200702/IncludeToken/Never"/>
</wsp:Policy>
</sp:SupportingTokens>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClass>com.ami.emscribe.security.PWCHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
And below the stacktrace I see in browser from Axis2:
Error: java.lang.RuntimeException: Incorrect inclusion value: -1 at org.apache.ws.secpolicy.model.Token.setInclusion(Token.java:56)
at org.apache.ws.secpolicy12.builders.UsernameTokenBuilder.build(UsernameTokenBuilder.java:45) at org.apache.ws.secpolicy12.builders.UsernameTokenBuilder.build(UsernameTokenBuilder.java:35)
at org.apache.neethi.AssertionBuilderFactoryImpl.invokeBuilder(AssertionBuilderFactoryImpl.java:138) at org.apache.neethi.AssertionBuilderFactoryImpl.build(AssertionBuilderFactoryImpl.java:117)
at org.apache.neethi.PolicyBuilder.processOperationElement(PolicyBuilder.java:224) at org.apache.neethi.PolicyBuilder.getPolicyOperator(PolicyBuilder.java:174) at org.apache.neethi.PolicyBuilder.getPolicy(PolicyBuilder.java:124) at org.apache.neethi.PolicyEngine.getPolicy(PolicyEngine.java:100) at org.apache.ws.secpolicy12.builders.SupportingTokensBuilder.build(SupportingTokensBuilder.java:78)
at org.apache.ws.secpolicy12.builders.SupportingTokensBuilder.build(SupportingTokensBuilder.java:39) at org.apache.neethi.AssertionBuilderFactoryImpl.invokeBuilder(AssertionBuilderFactoryImpl.java:138)
at org.apache.neethi.AssertionBuilderFactoryImpl.build(AssertionBuilderFactoryImpl.java:117) at org.apache.neethi.PolicyBuilder.processOperationElement(PolicyBuilder.java:224)
at org.apache.neethi.PolicyBuilder.getAllOperator(PolicyBuilder.java:184) at org.apache.neethi.PolicyBuilder.processOperationElement(PolicyBuilder.java:217)
at org.apache.neethi.PolicyBuilder.getExactlyOneOperator(PolicyBuilder.java:180) at org.apache.neethi.PolicyBuilder.processOperationElement(PolicyBuilder.java:215)
at org.apache.neethi.PolicyBuilder.getPolicyOperator(PolicyBuilder.java:174) at org.apache.neethi.PolicyBuilder.getPolicy(PolicyBuilder.java:124) at org.apache.neethi.PolicyEngine.getPolicy(PolicyEngine.java:100)
at org.apache.axis2.deployment.DescriptionBuilder.processPolicyElements(DescriptionBuilder.java:639) at org.apache.axis2.deployment.ServiceBuilder.populateService(ServiceBuilder.java:308)
at org.apache.axis2.deployment.repository.util.ArchiveReader.buildServiceGroup(ArchiveReader.java:101) at org.apache.axis2.deployment.repository.util.ArchiveReader.processServiceGroup(ArchiveReader.java:178)
at org.apache.axis2.deployment.ServiceDeployer.deploy(ServiceDeployer.java:82) at org.apache.axis2.deployment.repository.util.DeploymentFileData.deploy(DeploymentFileData.java:136)
at org.apache.axis2.deployment.DeploymentEngine.doDeploy(DeploymentEngine.java:813) at org.apache.axis2.deployment.repository.util.WSInfoList.update(WSInfoList.java:144)
at org.apache.axis2.deployment.RepositoryListener.update(RepositoryListener.java:377) at org.apache.axis2.deployment.RepositoryListener.checkServices(RepositoryListener.java:254)
at org.apache.axis2.deployment.DeploymentEngine.loadServices(DeploymentEngine.java:142) at org.apache.axis2.deployment.WarBasedAxisConfigurator.loadServices(WarBasedAxisConfigurator.java:283)
at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:95) at org.apache.axis2.transport.http.AxisServlet.initConfigContext(AxisServlet.java:584)
at org.apache.axis2.transport.http.AxisServlet.init(AxisServlet.java:454) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1228)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1147) at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:836)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at
Found an answer to my problem. Basically my policy security was wrong. I guess Iwas not following the specs for WSS4J. Here is where I found solution: http://www.developerblogger.com/1111_9173580/
I just changed my policy to look like the one below and it worked:
<wsp:Policy xmlns:wsp="http://www.w3.org/ns/ws-policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken10 />
<sp:HashPassword />
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClass>com.mycompany.security.PWCHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

Configure web service with both a Username Token and an x509 certificate using SVCConfigEditor

For a WCF web service client, is it possible to configure a web service with both a Username Token and an x509 certificate using SVCConfigEditor?
Is the following wsdl helpful in this interop scenario with an IBM Websphere web service?
Thank you,
Greg
<wsp:Policy wsu:Id="policy0" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<sp:AsymmetricBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:InitiatorToken>
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:X509Token>
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:WssX509V3Token11 />
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:X509Token>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:X509Token>
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:WssX509V3Token11 />
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:X509Token>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:TripleDesRsa15 />
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:AlgorithmSuite>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:SignedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<sp:Body />
</sp:SignedParts>
<sp:EncryptedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<sp:Body />
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702
Implements WS Security Policy 1.2 - UsernameToken 1.0 support
Not possibnle with plain svcutil, you need custom code. However you could create a binding (via code) with username supporting token and then use svcutil to define this binding.
I think its pretty obvious by now that SVCConfigEditor is not the tool. This was a suggestion that does not take into consideration custom binding, which it doesn't seem to be able to accommodate. Thank you to #Yaron for ideas even though I have not successfully implemented a solution yet.
although I would appreciate clarification #Yaron or a link to how to achieve the following, "instead of xml you could use svcutil, the key would be file-->Open-->Executable... where you choose the dll of your binding. Then it will be available normally like any other binding (you may need to dismiss or approve some message boxes)"**

JAX-WS ws-security UsernameToken authorization on server

I have created a web service in netbeans with METRO. I modified my web service wsit config for using Usernametoken authentication (without encryption).
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="NewWebService" targetNamespace="http://test.org/" xmlns:tns="http://test.org/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:fi="http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service" xmlns:tcp="http://java.sun.com/xml/ns/wsit/2006/09/policy/soaptcp/service" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sc="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
>
<message name="hello"/>
<message name="helloResponse"/>
<portType name="NewWebService">
<operation name="hello">
<input message="tns:hello"/>
<output message="tns:helloResponse"/>
</operation>
</portType>
<binding name="NewWebServicePortBinding" type="tns:NewWebService">
<wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#UsernameToken"/>
<operation name="hello">
<input></input>
<output></output>
</operation>
</binding>
<service name="NewWebService">
<port name="NewWebServicePort" binding="tns:NewWebServicePortBinding"/>
</service>
<!-- Policy for Username Token with plaintext password, sent from client to server only -->
<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken=".../IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
<wsss:ValidatorConfiguration wspp:visibility="private" xmlns:wsss="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy">
<wsss:Validator name="usernameValidator" classname="org.test.MyAuth"/>
</wsss:ValidatorConfiguration>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</definitions>
My PasswordValidator
package org.test;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback.PasswordValidationException;
import com.sun.xml.wss.impl.callback.PasswordValidationCallback.Request;
public class MyAuth implements PasswordValidationCallback.PasswordValidator
{
#Override
public boolean validate(Request request) throws PasswordValidationException {
PasswordValidationCallback.PlainTextPasswordRequest ptreq
= (PasswordValidationCallback.PlainTextPasswordRequest)request;
//Database query
return CheckUserInDateBase(ptreq.getPassword(), ptreq.getUsername());
}
}
Now i need authorize user with his username and password and check his role (every method of web service has annotation RolesAllowed). I have created SOAP handler for my web service where I trying to get username and password from soap headers, but header doesnt contains this information (when i get this header in handler).
Actually SOAP message looks like
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" 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" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<S:Header>
<macAddress xmlns="http://ws.mkyong.com/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next">F8-D1-11-01-36-20</macAddress>
<wsse:Security S:mustUnderstand="1">
<wsse:UsernameToken xmlns:ns15="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity" xmlns:ns14="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns13="http://www.w3.org/2003/05/soap-envelope" wsu:Id="uuid_48e60f1c-aea9-4bcc-897f-ef661fe2895b">
<wsse:Username>myusername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">mypass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
<ns2:hello xmlns:ns2="http://test.org/">
<name>aaaa</name>
</ns2:hello>
</S:Body>
</S:Envelope>
When I trying to extract header's child elements I'm getting only macAddress header (my custom header)
#Override
public boolean handleMessage(SOAPMessageContext context) {
Iterator i = context.getMessage().getSOAPPart().getEnvelope().getHeader().getChildElements();
return true;
}
So. How can I access to wssecurity headers? Or maybe has another way to check user role before execution web service method?
Instead of checking at your validator, store the username and password using ThreadLocal then apply your authentication roles within the service implementation as below. In my case, I used this approach to throw a custom exception.
My Validator:
/**
* #author SaudAlajmi
*
*/
public class PasswordValidator implements PasswordValidationCallback.PasswordValidator {
/* I used this approach because they need to throw a custom exception in case of authentication failure, as far as I know there is no such way
* to do it especially since the validator does not have access to the WebServiceContext, but this way and it is safe because every thread has
* it is own copy and that's why I used ThreadLocal;
*/
private static final ThreadLocal<String> username = new ThreadLocal<String>();
private static final ThreadLocal<String> password = new ThreadLocal<String>();
public boolean validate(Request request) throws PasswordValidationException {
PasswordValidationCallback.PlainTextPasswordRequest ptreq = (PasswordValidationCallback.PlainTextPasswordRequest) request;
password.set(ptreq.getPassword());
username.set(ptreq.getUsername());
return true;
}
public static String getUsername() {
String user = username.get();
username.remove();
return user;
}
public static String getPassword() {
String pwd= password.get();
password.remove();
return pwd;
}
}
My Service Impl:
String username = PasswordValidator.getUsername();
String password = PasswordValidator.getPassword();
if(username == null || !"test".equals(username) || password == null ||!"test".equals(password)){
faultInfo = new CommonErrorStructure();
faultInfo.setCode("KFSH000401");
faultInfo.setErrorText("Username/Password is incorrect");
faultInfo.setRaisedBy("PatientRecordService");
throw new GetPatientRecordError("Authentication Failure", faultInfo);
}
Reference:
Retrieve plaintext WS-Security password at service endpoint with Metro + WSIT?

WCF Web Service, Java Web Client, MustUnderstand headers not understood?

I'm hosting a WCF Web Service with the following WSDL (a simple service using wsHttpBinding and SSL for transport security):
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="MagicEightBallService" targetNamespace="http://tempuri.org/">
<wsp:Policy wsu:Id="WSHttpBinding_TransportSecurity_IMagicEightBallService_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"/>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
</wsp:Policy>
</sp:TransportBinding>
<wsaw:UsingAddressing/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://my.local.domain.name/MagicEightBall/MagicEightBallService.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://my.local.domain.name/MagicEightBall/MagicEightBallService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IMagicEightBallService_GetAdvice_InputMessage">
<wsdl:part name="parameters" element="tns:GetAdvice"/>
</wsdl:message>
<wsdl:message name="IMagicEightBallService_GetAdvice_OutputMessage">
<wsdl:part name="parameters" element="tns:GetAdviceResponse"/>
</wsdl:message>
<wsdl:portType name="IMagicEightBallService">
<wsdl:operation name="GetAdvice">
<wsdl:input wsaw:Action="http://tempuri.org/IMagicEightBallService/GetAdvice" message="tns:IMagicEightBallService_GetAdvice_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IMagicEightBallService/GetAdviceResponse" message="tns:IMagicEightBallService_GetAdvice_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_TransportSecurity_IMagicEightBallService" type="tns:IMagicEightBallService">
<wsp:PolicyReference URI="#WSHttpBinding_TransportSecurity_IMagicEightBallService_policy"/>
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetAdvice">
<soap12:operation soapAction="http://tempuri.org/IMagicEightBallService/GetAdvice" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MagicEightBallService">
<wsdl:port name="WSHttpBinding_TransportSecurity_IMagicEightBallService" binding="tns:WSHttpBinding_TransportSecurity_IMagicEightBallService">
<soap12:address location="https://localhost/MagicEightBall/MagicEightBallService.svc"/>
<wsa10:EndpointReference>
<wsa10:Address>
https://localhost/MagicEightBall/MagicEightBallService.svc
</wsa10:Address>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Why do I get errors when I try to consume this from Java? When I try to consume it using Axis2/Java, I get the error:
org.apache.axis2.AxisFault: Must Understand check failed for header http://www.w3.org/2005/08/addressing : Action
And when I try to use JAX-WS, I get the error:
javax.xml.ws.soap.SOAPFaultException: MustUnderstand headers:[{http://www.w3.org/2005/08/addressing}Action] are not understood
So far I haven't had any success with either of these, and I'm not sure whether a fix needs to be applied to the server or the client.
(See a related question I posted for more details, including the WCF Web.config).
Running:
ServiceClient sc = stub._getServiceClient();
sc.engageModule("addressing");
engages the Addressing module, fixing this issue.
I know the post is old, but someone may still face this problem.
I'm using JAX-WS, and I was having the same issue. After reading https://jax-ws.java.net/jax-ws-21-ea3/docs/wsaddressing.html#On_the_client_side I've found a solution that worked for me.
The code was breaking in the following line:
IFooService service = new FooService().getWSHttpBindingIFooService();
What I've done is the following:
IFooService service = new FooService().getWSHttpBindingIFooService(new javax.xml.ws.soap.AddressingFeature());
That's it.
also add addressing.mar and soapmonitor.mar to your library path.
I too had the same problem.
In my case the webservice's WSDL was created using WCF in .net and we are consuming it at JAVA side. After several tries I noticed that the corresponding header was missing in the web service. I asked my dotnet team to add a - port name in the webservice.This port name just a normal name in the web service. This was needed because at JAVA side we need port type and port name to actually access the webservice.
Try to add below lines at the .net side inside the service and then try to consume at JAVA side.
[ServiceContract(Namespace = "BookStockWebService", Name = "BookStock")]
[ServiceBehavior(Namespace = "BookStockWebServiceport", Name = "BookStockPort")]
If client has been generated using Apache CXF and facing this issue, then below helps:
Add below annotation to IService interface:
#Addressing(enabled=true, required=false)
In client class that is where the service is being obtained for calling:
ServiceImpl service = new ServiceImpl(wsdl,service); IService port = service.getWSHttpBindingIService(new AddressingFeature(true));
Import for AddressingFeature is javax.xml.ws.soap.AddressingFeature;