Pages

Saturday, July 28, 2012

WS-Security Protocol with .NET – A Overview


WS-Security is a security mechanism for web services coined by IBM, Microsoft and VeriSign. WS-Security introduces the concept of security tokens. These XML-based tokens contain claims about the sender of a SOAP message, and can include data sufficient to prove these claims. Username tokens, which will be the focus of this article, can contain a username and optionally a password or a cryptographically-derived password hash. Signed security tokens, such as X.509 or Kerberos-based tokens, are binary security tokens encoded as base-64 binary XML. They include cryptographic endorsements made by a token-issuing authority.

WSE2.0 (Web Service Enhancements) Features
This section describes the new and enhanced features included in the WSE 2.0 and its implementation in .NET.
Policy
WSE version 2.0 enables developers to use configuration files to specify requirements for receiving and sending messages. Now those requirements, known as policy assertions, can be expressed in a configuration file. When policy assertions are configured, WSE runtime checks incoming or outgoing SOAP messages to determine whether they comply with the policy assertions; when they do not, WSE runtime returns a SOAP fault. WSE has a set of predefined policy assertions, such as the requirement that the body of the SOAP message be signed with an X.509 certificate. In addition, the policy system can be extended to include custom policy assertions.
WS-Trust and Security Context Tokens
WSE's support of the WS-Trust and WS-Secure Conversation specifications provides the capability to programmatically request a security token using a SOAP message, and that token can be used for a series of SOAP messages between a SOAP message sender and a target Web service. WSE allows you to build a security token service or configure one that issues security context tokens. When configured to issue security context tokens, a SOAP message sender can use the token to sign and/or encrypt a series of SOAP messages, known as a conversation, between a SOAP message sender and the target Web service. 
Kerberos Security Tokens
WSE supports the use of security tokens based on Kerberos tickets. Kerberos tickets can be used to digitally sign and encrypt SOAP messages, along with authorizing access to a Web service based on a Kerberos security token.
Role-based Security Using Security Tokens
WSE supports role-based authorization for SOAP messages by constructing a principal from a security token in the SOAP message, such as the one used to digitally sign the SOAP message. 
Signing and Encrypting Security Tokens
When a security token is added to a SOAP message, it is added to the SOAP message in the form of an XML element in the WS-Security SOAP header. That XML element can now be digitally signed or encrypted. This can be very useful when the security token is a Username Token, which is based upon a user name and password especially if the password is sent in plaintext. And when you use role-based security with a Username Token, the password must be sent in plaintext. Therefore, encrypting the Username Token containing a plaintext password can make it more difficult for an intermediary to steal a user's password.
SOAP Messaging
With SOAP messaging, WSE supports a flexible and lightweight mechanism for sending and receiving SOAP messages. This mechanism allows applications to switch between the TCP and HTTP transport protocols relatively easily. 
How to implement security using WSE2.0?
To implement the WS-Security specification in your Web service or consuming client application, you must be able to write security elements to and read them from your SOAP messages, and you must have access to standard cryptographic algorithms. All messages sent to a WSE-enabled application must contain at least one security token.
System Requirements
  • Windows Server 2003 
  • Microsoft Internet Information Services (IIS) 5.0, 5.1, or 6.0 
  • Microsoft .NET Framework version 1.1 or later
WSE2.0 can be downloaded at the following location:
http://www.microsoft.com/downloads/details.aspx?FamilyId=FC5F06C5-821F-41D3-A4FE-6C7B56423841&displaylang=en 
Step1: Install the WSE2.0 Service Pack.
Step2: Open a project (applies to both windows and web applications) and right click the solution file. Click on the WSE2.0 settings window will be displayed as shown below:


Figure 1. Setting up WSE 2.0.
Step3: On Clicking on the WSE Settings2.0 window a popup properties windows as shown below will be displayed. Check the on "Enable the project for Web Services Enhancements" check box. See Figure 2.


Figure 2. 
Step4: Steps 1 through step3 should be repeated for the project where the web service is hosted.
Step5: Now let's write a simple piece of code which accesses the web service method on which the WSE2.0 settings have been implemented.
Assuming we have a Web Service named Weatherservice already exists we write the following lines of code to access a method called GetTemperature ( ) in the project accessing the Weather web service. 
Weatherservice wservice = new Weatherservice(); // Get the SoapContext object for the messageSoapContext context = wservice.RequestSoapContext;// Instantiate a new UsernameToken object.UsernameToken token = new UsernameToken (name, 
Password, PasswordOption.SendNone);
// Add the token to the SoapContext.context.Security.Tokens.Add(token);// Generate a signature using the username token, // and add the signature to the SoapContext.context.Security.Elements.Add(new Signature(token));try{// Call the Web method.String temperature = service.GetTemperature();
}
catch(Exception ex)
{
// Error handling}
We have successfully called a web service method which implements WSE 2.0.
Conclusion
WS-Security is one of the best ways of securing SOAP messages. It can be easily implemented there by reducing a lot of coding effort. It provides us the flexibility of using different entities as security tokens (Username Token, X.509 certificates etc).It secures the applications by blocking all the unauthenticated messages and messages having a invalid digital signature.
Reference

How to Call Web Service in Android Using SOAP


Download Files:
 
Introduction

In this tutorial, we will learn how to call a Web Service using SOAP (Simple Object Access Protocol). 

Prerequisites

Web Service, SOAP envelope, WSDL (Web Service Definition Language)

What is SOAP?

SOAP is a protocol specification for exchanging structured information in the implementation of Web Services in computer networks. It relies on Extensible Markup Language (XML) for its message format, and usually relies on other Application Layer protocols, most notably Hypertext Transfer Protocol (HTTP) and Simple Mail Transfer Protocol (SMTP), for message negotiation and transmission. The following is the structure of SOAP Envelope:

AndWeb1.jpg

Step 1:

First create a "New Android Project". Name it "WebServiceDemo" like below.

AndWeb2.jpg

AndWeb3.jpg

AndWeb4.jpg

Step 2:

Now right-click on your "WebServiceDemo" project and select "New -> Folder"

AndWeb5.jpg


Now, give it a name it "lib". We need to add a SOAP library into this directory.

AndWeb6.jpg

Step 3:

Now download the attached library named "ksoap2-android-assembly-2.6.0-jar-with-dependencies.jar". Copy that file and paste it into the "lib" directory.

After copying, do the following steps:
  1. Right-click on the project.
  2. Go "Build Path -> Configure Build Path"

    AndWeb7.jpg
     
  3. Now, click on "Add Jars" and select ".jar" file from "project -> lib" directory.

    AndWeb8.jpg
     
  4. Click on "Ok" to finish the procedure of adding library to Android application.
Step 4:

Next we need to create a layout of screen. To do so, go to "WebServiceDemo -> res -> layout -> main.xml"
Open this xml file in editing mode, and place below code.

Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fahrenheit"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/txtFar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Celsius"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/txtCel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btnFar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="Convert To Celsius" />

        <Button
            android:id="@+id/btnCel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="Convert To Fahrenheit" />

    </LinearLayout>


    <Button
        android:id="@+id/btnClear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Clear" />

</LinearLayout>

This will create simple following screen.

AndWeb9.jpg


Step 5:

Now, find out any Web Service, make sure that you can view its WSDL file by writing "?wsdl" after that address.

For example, you have a web service likehttp://www.w3schools.com/webservices/tempconvert.asmx",  so to view the WSDL file, simply write "?wsdl" after this address like:
http://www.w3schools.com/webservices/tempconvert.asmx?WSDL".  

You are now done with the Web Service part from the internet. Now you need to extend some portion of the WSDL file. Open the first link in your browser, it will display 2 conversions for you:
  • CelsiusToFahrenheit
  • FahrenheitToCelsius
Select anyone of them, and you will see following screen:

AndWeb10.jpg

For CelsiusToFahrenheit:
  1. NAMESPACE = "http://tempuri.org/";
  2. METHOD_NAME = "CelsiusToFahrenheit";
For FahrenheitToCelsius:
  1. NAMESPACE = "http://tempuri.org/";
  2. METHOD_NAME = " FahrenheitToCelsius ";
Step 6:

You need to understand some classes before proceeding to use a Web Service.
  1. SoapObject ( 

    A simple dynamic object that can be used to build SOAP calls without implementing KvmSerializable. Essentially, this is what goes inside the body of a SOAP envelope - it is the direct subelement of the body and all further sub elements. Instead of this class, custom classes can be used if they implement the KvmSerializable interface.

    Constructor:

    SoapObject (java.lang.String namespace, java.lang.String method) 
     
  2. SoapSerializationEnvelope

    This class extends the SoapEnvelope with Soap Serialization functionality.

    Constructor:
    SoapSerializationEnvelope (int version)

    Fields:
    Type
    Field
    Description
    boolean
    dotNet
    Set this variable to true for compatibility with what seems to be the default encoding for .Net-Services.
    Methods:
    Return Type
    Method Name
    Description
    void
    setOutputSoapObject(java.lang.Object soapObject)
    Assigns the object to the envelope as the outbound message for the soap call.

  3. HttpTransportSE (org.ksoap2.transport.HttpTransportSE)

    A J2SE based HttpTransport layer.

    Constructor:

    HttpTransportSE(java.lang.String url)

    Method:
    Return Type
    Method
    Description
    void
    call(java.lang.String SoapAction, SoapEnvelope envelope)
    set the desired soapAction header field
Step 7:

Open your "WebServiceDemo -> src -> WebServiceDemoActivity.java" file and enterr following code:

WebServiceDemoActivity.java
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class WebServiceDemoActivity extends Activity
{
    /** Called when the activity is first created. */
      private static String SOAP_ACTION1 = "http://tempuri.org/FahrenheitToCelsius";
      private static String SOAP_ACTION2 = "http://tempuri.org/CelsiusToFahrenheit";
      private static String NAMESPACE = "http://tempuri.org/";
      private static String METHOD_NAME1 = "FahrenheitToCelsius";
      private static String METHOD_NAME2 = "CelsiusToFahrenheit";
      private static String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";

      Button btnFar,btnCel,btnClear;
      EditText txtFar,txtCel;
     
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        btnFar = (Button)findViewById(R.id.btnFar);
        btnCel = (Button)findViewById(R.id.btnCel);
        btnClear = (Button)findViewById(R.id.btnClear);
        txtFar = (EditText)findViewById(R.id.txtFar);
        txtCel = (EditText)findViewById(R.id.txtCel);
       
        btnFar.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {
                        //Initialize soap request + add parameters
                  SoapObject request = new SoapObject(NAMESPACEMETHOD_NAME1);       
                 
                  //Use this to add parameters
                  request.addProperty("Fahrenheit",txtFar.getText().toString());
                 
                  //Declare the version of the SOAP request
                  SoapSerializationEnvelope envelope = newSoapSerializationEnvelope(SoapEnvelope.VER11);
                 
                  envelope.setOutputSoapObject(request);
                  envelope.dotNet = true;
                 
                  try {
                        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
                       
                        //this is the actual part that will call the webservice
                        androidHttpTransport.call(SOAP_ACTION1, envelope);
                       
                        // Get the SoapResult from the envelope body.
                        SoapObject result = (SoapObject)envelope.bodyIn;

                        if(result != null)
                        {
                              //Get the first property and change the label text
                              txtCel.setText(result.getProperty(0).toString());
                        }
                        else
                        {
                              Toast.makeText(getApplicationContext(), "No Response",Toast.LENGTH_LONG).show();
                        }
                  } catch (Exception e) {
                        e.printStackTrace();
                  }
                  }
            });
       
        btnCel.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {
                        //Initialize soap request + add parameters
                  SoapObject request = new SoapObject(NAMESPACEMETHOD_NAME2);       
                 
                  //Use this to add parameters
                  request.addProperty("Celsius",txtCel.getText().toString());
                 
                  //Declare the version of the SOAP request
                  SoapSerializationEnvelope envelope = newSoapSerializationEnvelope(SoapEnvelope.VER11);
                 
                  envelope.setOutputSoapObject(request);
                  envelope.dotNet = true;
                 
                  try {
                        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
                       
                        //this is the actual part that will call the webservice
                        androidHttpTransport.call(SOAP_ACTION2, envelope);
                       
                        // Get the SoapResult from the envelope body.
                        SoapObject result = (SoapObject)envelope.bodyIn;

                        if(result != null)
                        {
                              //Get the first property and change the label text
                              txtFar.setText(result.getProperty(0).toString());
                        }
                        else
                        {
                              Toast.makeText(getApplicationContext(), "No Response",Toast.LENGTH_LONG).show();
                        }
                  } catch (Exception e) {
                        e.printStackTrace();
                  }
                  }
            });
       
        btnClear.setOnClickListener(new View.OnClickListener()
        {
                  @Override
                  public void onClick(View v)
                  {
                        txtCel.setText("");
                        txtFar.setText("");
                  }
            });
    }
}

Step 8:

Now, open your "WebServiceDemo -> android.manifest" file. Add the following line before the <application> tag:

<uses-permission android:name="android.permission.INTERNET" />

This will allow the application to use the internet.

Step 9:

Run your application in the Android Cell. You will get the following outcome:

Note: In the emulator, we need to fix a proxy, so try the application in an Android Cell.

AndWeb11.jpg

Summary

In this brief tutorial, we learned about Web Services, SOAP envelopes, WSDL files, HTTP transport, and how to use the in an Android application.