Thursday, May 14, 2015

WS-Security Password Digest Policy implementation with CXF


This article will help to learn WS-Security Password Digest Policy implementation WSDL based approach. To implement 3 steps needs to be followed

Step 1: Add the following Password Digest policy xml snippet at the end of the service declaration in the WSDL

  <wsp:policy wsu:id="CalcPlaintextPolicy">
         <sp:supportingtokens>
             <wsp:policy>
                 <sp:usernametoken sp:includetoken=
                             "http://docs.oasis-open.org/ws-sx/
                                ws-securitypolicy/200702/
                                  IncludeToken/AlwaysToRecipient">
                     <wsp:policy>
                         <sp:hashpassword>
                     </sp:hashpassword></wsp:policy>
                 </sp:usernametoken>
             </wsp:policy>
         </sp:supportingtokens>
     </wsp:policy>

Example:

 <wsdl:service name="CalculatorService">
    <wsdl:port binding="impl:CalculatorSoapBinding" name="Calculator">
      <wsdlsoap:address location="http://localhost:8080/Calculator/services">
    </wsdlsoap:address></wsdl:port>
  </wsdl:service>
     <!-- STARTS AFTER THE SERVICE   -->
     <wsp:policy wsu:id="CalcPlaintextPolicy">
         <sp:supportingtokens>
             <wsp:policy>
                 <sp:usernametoken sp:includetoken="
				         http://docs.oasis-open.org/ws-sx/
				           ws-securitypolicy/200702/IncludeToken/
						   AlwaysToRecipient">
                     <wsp:policy>
                          <!-- MAIN CHANGE ON THE  WSDL IS  -->
                         <sp:hashpassword>
                     </sp:hashpassword></wsp:policy>
                 </sp:usernametoken>
             </wsp:policy>
         </sp:supportingtokens>
     </wsp:policy>  
    <!-- ENDS BEFORE THE WSDL DEFINITION -->

Step 2: Add the following policy reference snippet after the wsdl binding section of the WSDL

  <wsp:policyreference uri="#CalcPlaintextPolicy"> </wsp:policyreference>

Example:

  <wsdl:binding name="CalculatorSoapBinding" type="impl:Calculator">
    <!--- START OF THE POLICY REFERENCE  --> 
    <wsp:policyreference uri="#CalcPlaintextPolicy">
    <wsdlsoap:binding transport="http://schemas.xmlsoap.org/soap/http">
    <wsdl:operation name="add">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="addRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="addResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
    <wsdl:operation name="sub">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="subRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="subResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
    <wsdl:operation name="multi">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="multiRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="multiResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
    <wsdl:operation name="div">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="divRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="divResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
  </wsdlsoap:binding>
   <!--- END OF THE POLICY REFERENCE  -->
  </wsp:policyreference>
 </wsdl:binding>

Step 3: Use the below given snippet to configure the cxf-bean.xml.

Example:

<jaxws:endpoint address="/calculator" id="calculator" implementor="com.elan.calc.service.impl.CalculatorImpl">
  <jaxws:features>
   <bean class="org.apache.cxf.feature.LoggingFeature">
  </bean></jaxws:features>
  <jaxws:properties>
            <entry key="ws-security.username" value="wsuser">        
            <entry key="ws-security.callback-handler" value-ref="wsSecPasswordCallback">
        </entry></entry></jaxws:properties>   
 </jaxws:endpoint>
 <bean class="com.elan.calc.ws.service.PasswordCallbackHandler" id="wsSecPasswordCallback">
</bean>

Refer the Example: callbackhandler

package com.elan.calc.ws.service;
import java.io.IOException;


import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class PasswordCallbackHandler implements CallbackHandler {

 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
  WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
  System.out.println("identifier: " + pc.getIdentifier());

  if (pc.getIdentifier().equals("wsuser")) {
   // set the password on the callback. This will later be compared to // the // password which was sent from the client.
   pc.setPassword("ws=USER");
  }
 }
}

WS Security namespaces used in the wsdl

 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:wsaws="http://www.w3.org/2005/08/addressing" 
 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" 
 xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"
 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"


Your ws security plain Digest policy implementation is completed successfully!!! You can also download complete working code from the following location. Thanks for visiting my learning blog.
Download Source Code

Wednesday, May 13, 2015

WS-Security Password PlainText/Digest Policy CXF Client Impl

This article will help to create WS -Security Client based CXF. It works for Plain password and Password Digest. User have to follow few steps to get one Jar created for the WS Client

Step 1: Create Java project and convert the project to maven based project. Copy your WSDL into the wsdl folder present in the project. provide wsdl path(even URL) in the cxf-codegen-plugin

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>2.1.2</version>
    <executions>
     <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
       <sourceRoot>${basedir}/src/</sourceRoot>
       <wsdlOptions>
        <wsdlOption>
         <wsdl>${basedir}/wsdl/CalculatorImpl.wsdl</wsdl>
        </wsdlOption>
       </wsdlOptions>
      </configuration>
      <goals>
       <goal>wsdl2java</goal>
      </goals>
     </execution>
    </executions>
   </plugin>

Write the client code like below and pass your callback and username for the WS Security

package com.elan.calc.service.impl;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import javax.xml.ws.BindingProvider;
import com.elan.calc.domain.Input;

public class WSClient {
     public static void main(String[] args) throws MalformedURLException {
      URL wsdlURL= new URL("http://localhost:8080/Calculator/services/calculator?wsdl");
      CalculatorService service = new CalculatorService(wsdlURL);
         Calculator port = service.getCalculator();
         Map ctx = ((BindingProvider)port).getRequestContext();
         ctx.put("ws-security.username", "wsuser");
         ctx.put("ws-security.callback-handler", PasswordCallbackHandler.class.getName());
         Input input = new Input();
         input.setInputA(10);
         input.setInputA(20);
         int ret = port.add(input);
         System.out.println(ret);
 }
}

Callback Example:

package com.elan.calc.service.impl;

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class PasswordCallbackHandler implements CallbackHandler {

 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
  WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
  System.out.println("identifier: " + pc.getIdentifier());

  if (pc.getIdentifier().equals("wsuser")) {
   // set the password on the callback. This will later be compared to // the // password which was sent from the client.
   pc.setPassword("ws=USER");
  }
 }
}

Example WS-security soap envelope Plain password

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:impl="http://impl.service.calc.elan.com" 
xmlns:dom="http://domain.calc.elan.com">
   <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>wsuser</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/
			oasis-200401-wss-username-token-profile-1.0
			#PasswordText">ws=USER</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
     </soapenv:Header>
   <soapenv:Body>
      <impl:add>
         <impl:input>
            <dom:inputA>5</dom:inputA>
            <dom:inputB>5</dom:inputB>
         </impl:input>
      </impl:add>
   </soapenv:Body>
</soapenv:Envelope>

Example WS-security soap envelope Password Digest

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
	<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
		<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-B7CAA505B63AE99FD314316382790611">
			<wsse:Username>wsuser</wsse:Username>
			<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">doAUEzig+QRcXp+04R/7zZx96oQ=</wsse:Password>
			<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">YNLZe1hq693qGsboH5dCag==</wsse:Nonce>
			<wsu:Created>2015-05-14T21:17:59.059Z</wsu:Created>
		</wsse:UsernameToken>
	</wsse:Security>
</soap:Header>
<soap:Body>
	<ns2:add xmlns="http://domain.calc.elan.com" xmlns:ns2="http://impl.service.calc.elan.com">
		<ns2:input>
			<inputA>20</inputA>
			<inputB>14</inputB>
		</ns2:input>
		</ns2:add>
	</soap:Body>
	</soap:Envelope>

your ws security plain text/Digest Password policy Client implementation is completed successfully!!! You can also download complete working code from the following location. Thanks for visiting my learning blog.

Download Source Code

Thursday, May 7, 2015

WS-Security PlainText Policy implementations with CXF

This article will help to learn WS-Security PlainText Policy implementation WSDL based approach. To implement 3 steps needs to be followed

Step 1: Add the following plain text policy xml snippet at the end of the service declaration in the WSDL

  <wsp:policy wsu:id="CalcPlaintextPolicy">
         <sp:supportingtokens>
             <wsp:policy>
                 <sp:usernametoken sp:includetoken=
				 "http://docs.oasis-open.org/ws-sx/
				        ws-securitypolicy/200702/
						IncludeToken/AlwaysToRecipient">
                     <wsp:policy>
                 </wsp:policy></sp:usernametoken>
             </wsp:policy>
         </sp:supportingtokens>
     </wsp:policy>
 

Example:

 <wsdl:service name="CalculatorService">
    <wsdl:port binding="impl:CalculatorSoapBinding" name="Calculator">
      <wsdlsoap:address location="http://localhost:8080/Calculator/services">
    </wsdlsoap:address></wsdl:port>
  </wsdl:service>
     <!-- STARTS AFTER THE SERVICE   -->
    <wsp:policy wsu:id="CalcPlaintextPolicy">
         <sp:supportingtokens>
             <wsp:policy>
                 <sp:usernametoken sp:includetoken=
				 "http://docs.oasis-open.org/ws-sx/
				          ws-securitypolicy/200702/IncludeToken/
						  AlwaysToRecipient">
                     <wsp:policy>
                 </wsp:policy></sp:usernametoken>
             </wsp:policy>
         </sp:supportingtokens>
     </wsp:policy>
    <!-- ENDS BEFORE THE WSDL DEFINITION -->
</wsdl:definitions>  

Step 2: Add the following plain text policy reference snippet after the wsdl binding section of the WSDL

  <wsp:policyreference uri="#CalcPlaintextPolicy"> 

Example:

  <wsdl:binding name="CalculatorSoapBinding" type="impl:Calculator">
    <!--- START OF THE POLICY REFERENCE  --> 
    <wsp:policyreference uri="#CalcPlaintextPolicy">
    <wsdlsoap:binding transport="http://schemas.xmlsoap.org/soap/http">
    <wsdl:operation name="add">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="addRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="addResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
    <wsdl:operation name="sub">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="subRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="subResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
    <wsdl:operation name="multi">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="multiRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="multiResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
    <wsdl:operation name="div">
      <wsdlsoap:operation soapaction="">
      <wsdl:input name="divRequest">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:input>
      <wsdl:output name="divResponse">
        <wsdlsoap:body use="literal">
      </wsdlsoap:body></wsdl:output>
    </wsdlsoap:operation></wsdl:operation>
  </wsdlsoap:binding>
   <!--- END OF THE POLICY REFERENCE  -->
  </wsp:policyreference>
 </wsdl:binding>

Step 3: Use the below given snippet to configure the cxf-bean.xml.

Example:

<jaxws:endpoint address="/calculator" id="calculator" 
implementor="com.elan.calc.service.impl.CalculatorImpl">
  <jaxws:features>
   <bean class="org.apache.cxf.feature.LoggingFeature">
  </bean></jaxws:features>
  <jaxws:properties>
            <entry key="ws-security.username" value="wsuser">        
            <entry key="ws-security.callback-handler" 
			value-ref="wsSecPasswordCallback">
        </entry></entry></jaxws:properties>   
 </jaxws:endpoint>
 <bean class="com.elan.calc.ws.service.PasswordCallbackHandler" 
 id="wsSecPasswordCallback">
</bean>

Refer the Example: callbackhandler

package com.elan.calc.ws.service;
import java.io.IOException;


import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class PasswordCallbackHandler implements CallbackHandler {

 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
  WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
  System.out.println("identifier: " + pc.getIdentifier());

  if (pc.getIdentifier().equals("wsuser")) {
   // set the password on the callback. This will later be compared to // the // password which was sent from the client.
   pc.setPassword("ws=USER");
  }
 }
}

WS Security namespaces used in the wsdl

 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:wsaws="http://www.w3.org/2005/08/addressing" 
 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" 
 xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"


your ws security plain text policy implementation is completed successfully!!! You can also download complete working code from the following location. Thanks for visiting my learning blog.

Download Source Code

Csvson

/* * Copyright (c) 2020. Virtualan Software Contributors (https://virtualan.io) * * Licensed under the Apache License, Version 2.0 (...