Exchange UserCredential between client and webservice in.NET

No.of Views1528
Bookmarked0 times
Downloads 
Votes0
By  RRaveen   On  15 Feb 2010 22:02:47
Tag : Web Service , How to
Exchange UserCredential between client and webservice in.NET
emailbookmarkadd commentsprint

Images in this article missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at info@codegain.com

 

Content

1.Introduction
2.Web service
3.Soap Header
4.Web service Implementation
5.SoapHeader Implementation
6.Build token using Cryptography
7.Invoke Web service in client and pass the user credential
8.Conclusion

Introduction

The purpose this article is to explore the exchange of user credentials using the soap header between client and webs service with Cryptography.Nowadays web service is most popular platform independent services.so most of the organization they would have to all data integration using web services. for example CRM.So this point most of developer they ask question about how about security strength.SOAP has solution for that it. When we implement web service you can use the SOAP Header and explicit you override to exchange the user security token between client and server.

If you are a beginner for web service , To get more information about the web service just visit here
1.http://www.w3schools.com/webservices/default.asp
2.http://www.west-wind.com/presentations/dotnetwebservices/DotNetWebServices.asp


Web Services

Web services are application components
  • Web services communicate using open protocols
  • Web services are self-contained and self-describing
  • Web services can be discovered using UDDI
  • Web services can be used by other applications
  • XML is the basis for Web services

Soap Header

The optional SOAP Header element contains application-specific information (like authentication, payment, etc) about the SOAP message.If the Header element is present, it must be the first child element of the Envelope element.

Implementation

Lets start web service implementation to this you need open visual studio , click File menu then click new website you will get collection project temple window from that you need select ASP.NET web service (if you are using Visual Studio 2008) and supply website name as "http://localhost/UserCredentialWithSHInWebService" and click ok button. take a look following figure to clear understanding.

Image Loading...

Now we created project next steps we need do two important work first you we need create SOAP Header class.

Soap header Implementation

Right on the web project then add new class call as "SoapUserAuthenticationHeader" and click OK button.here you need inherit your SoapUserAuthenticationHeader class from the SoapHeader, then only you could add attribute to web service method.The SoapUserAuthenticationHeader class file like followings.


SoapUserAuthenticationHeader.cs
{codecitation class="brush: csharp; gutter: true;" width="650px"}

using System;
using System.Xml;
using System.Xml.Serialization;
using System.Web.Services.Protocols;


public class SoapUserAuthenticationHeader : SoapHeader
{
public SoapUserAuthenticationHeader()
{

}
public SoapUserAuthenticationHeader(string username, string token)
{
this.username = username;
this.token = token;
}
string username;

public string Username
{
get { return username; }
set { username = value; }
}
string token;

public string Token
{
get { return token; }
set { token = value; }
}

}
{/codecitation}

SoapUserAuthenticationHeader class is have two properties first for user name and second one for user taken(encrypted password).And important note here you should inherit from SoapHeader class.

Web service Implementation

To this I'm going to take a simple example, if you are have sent valid token to server then server return success message or else return failed message.

DataServices.cs
{codecitation class="brush: csharp; gutter: true;" width="650px"}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

///
/// Summary description for DataServices
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class DataServices : System.Web.Services.WebService
{

public SoapUserAuthenticationHeader UserCredential;


[WebMethod]
[SoapHeader("UserCredential", Direction = SoapHeaderDirection.In)]
public string Message(string[] data)
{
if (UserCredential != null)
{
if (SecurityManager.IsValidUser(UserCredential))
{
return "You are welcome";
}
}
return "You are token not valid, please try with new token";
}


}

{/codecitation}

Let's look [SoapHeader("UserCredential", Direction = SoapHeaderDirection.In)] in the above code.Just explicit tell to web service method you need a soap header and this direction as IN

One more class i were added to web service project to make easy

SecurityManager.cs

{codecitation class="brush: csharp; gutter: true;" width="650px"}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

///
/// Summary description for SecurityManager
///
public class SecurityManager
{
public static bool IsValidUser(SoapUserAuthenticationHeader usercredential)
{
string encryptedPass = usercredential.Token;
string plianPass = new CustomSecutiry().Decrypt(encryptedPass);
if (usercredential.Username.Equals("test"))
{
if (plianPass.Equals("pass"))
{
return true;
}
}
return false;
}
}

{/codecitation}

In this class i have a method to valid user name ans token .and look at this line string plianPass = new CustomSecutiry().Decrypt(encryptedPass);

When user pass password from the client just sent as encrypted token to server.server need decrypt that token and then check with password value.To this i have a common class call as "CutomSecutiy" this class have implemented methods to encrypt and decrypt using Cryptography.

Build token using Cryptography

CutomSecutiy.cs

{codecitation class="brush: csharp; gutter: true;" width="650px"}
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class CustomSecutiry
{
public CustomSecutiry()
{
// Default symmetric algorithm
mCryptoService = new RijndaelManaged();
mCryptoService.Mode = CipherMode.CBC;
mAlgorithm = ServiceProviderEnum.Rijndael;
}

public CustomSecutiry(ServiceProviderEnum serviceProvider)
{
// Select symmetric algorithm
switch (serviceProvider)
{
case ServiceProviderEnum.Rijndael:
mCryptoService = new RijndaelManaged();
mAlgorithm = ServiceProviderEnum.Rijndael;
break;
case ServiceProviderEnum.RC2:
mCryptoService = new RC2CryptoServiceProvider();
mAlgorithm = ServiceProviderEnum.RC2;
break;
case ServiceProviderEnum.DES:
mCryptoService = new DESCryptoServiceProvider();
mAlgorithm = ServiceProviderEnum.DES;
break;
case ServiceProviderEnum.TripleDES:
mCryptoService = new TripleDESCryptoServiceProvider();
mAlgorithm = ServiceProviderEnum.TripleDES;
break;
}
mCryptoService.Mode = CipherMode.CBC;
}

public CustomSecutiry(string serviceProviderName)
{
try
{
// Select symmetric algorithm
switch (serviceProviderName.ToLower())
{
case "rijndael":
serviceProviderName = "Rijndael";
mAlgorithm = ServiceProviderEnum.Rijndael;
break;
case "rc2":
serviceProviderName = "RC2";
mAlgorithm = ServiceProviderEnum.RC2;
break;
case "des":
serviceProviderName = "DES";
mAlgorithm = ServiceProviderEnum.DES;
break;
case "tripledes":
serviceProviderName = "TripleDES";
mAlgorithm = ServiceProviderEnum.TripleDES;
break;
}

// Set symmetric algorithm
mCryptoService = (SymmetricAlgorithm)CryptoConfig.CreateFromName(serviceProviderName);
mCryptoService.Mode = CipherMode.CBC;
}
catch
{
throw;
}
}
#region Symmetric cryptography class...

#region Private members...
//private string mKey = "wqdj~yriu!@*k0_^fa7431%p$#=@hd+&";
private string mKey = "wqdj~yriu!@*k0_^fa7431%p$#=@hd+&*&NSGTHYT%$D&*JK(^%GFDE$%TYJ&^%R";
private string mSalt = "*&%^hr^";
private ServiceProviderEnum mAlgorithm;
private SymmetricAlgorithm mCryptoService;

private void SetLegalIV()
{
// Set symmetric algorithm
switch (mAlgorithm)
{
case ServiceProviderEnum.Rijndael:
mCryptoService.IV = new byte[] { 0xf, 0x6f, 0x13, 0x2e, 0x35, 0xc2, 0xcd, 0xf9, 0x5, 0x46, 0x9c, 0xea, 0xa8, 0x4b, 0x73, 0xcc };
break;
default:
mCryptoService.IV = new byte[] { 0xf, 0x6f, 0x13, 0x2e, 0x35, 0xc2, 0xcd, 0xf9 };
break;
}
}

#endregion

#region Public interfaces...

public enum ServiceProviderEnum : int
{
// Supported service providers
Rijndael,
RC2,
DES,
TripleDES
}
public virtual byte[] GetLegalKey()
{
// Adjust key if necessary, and return a valid key
if (mCryptoService.LegalKeySizes.Length > 0)
{
// Key sizes in bits
int keySize = mKey.Length * 8;
int minSize = mCryptoService.LegalKeySizes[0].MinSize;
int maxSize = mCryptoService.LegalKeySizes[0].MaxSize;
int skipSize = mCryptoService.LegalKeySizes[0].SkipSize;

if (keySize > maxSize)
{
// Extract maximum size allowed
mKey = mKey.Substring(0, maxSize / 8);
}
else if (keySize < maxSize)
{
// Set valid size
int validSize = (keySize <= minSize) ? minSize : (keySize - keySize % skipSize) + skipSize;
if (keySize < validSize)
{
// Pad the key with asterisk to make up the size
mKey = mKey.PadRight(validSize / 8, '*');
}
}
}
PasswordDeriveBytes key = new PasswordDeriveBytes(mKey, ASCIIEncoding.ASCII.GetBytes(mSalt));
return key.GetBytes(mKey.Length);
}

public virtual string Encrypt(string plainText)
{
byte[] plainByte = ASCIIEncoding.ASCII.GetBytes(plainText);
byte[] keyByte = GetLegalKey();

// Set private key
mCryptoService.Key = keyByte;
SetLegalIV();

// Encryptor object
ICryptoTransform cryptoTransform = mCryptoService.CreateEncryptor();

// Memory stream object
MemoryStream ms = new MemoryStream();

// Crpto stream object
CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write);

// Write encrypted byte to memory stream
cs.Write(plainByte, 0, plainByte.Length);
cs.FlushFinalBlock();

// Get the encrypted byte length
byte[] cryptoByte = ms.ToArray();

// Convert into base 64 to enable result to be used in Xml
return Convert.ToBase64String(cryptoByte, 0, cryptoByte.GetLength(0));
}

public virtual string Decrypt(string cryptoText)
{
// Convert from base 64 string to bytes
byte[] cryptoByte = Convert.FromBase64String(cryptoText);
byte[] keyByte = GetLegalKey();

// Set private key
mCryptoService.Key = keyByte;
SetLegalIV();

// Decryptor object
ICryptoTransform cryptoTransform = mCryptoService.CreateDecryptor();
try
{
// Memory stream object
MemoryStream ms = new MemoryStream(cryptoByte, 0, cryptoByte.Length);

// Crpto stream object
CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read);

// Get the result from the Crypto stream
StreamReader sr = new StreamReader(cs);
return sr.ReadToEnd();
}
catch
{
return null;
}
}
#endregion

#endregion


}

{/codecitation}

Look like everything fine in server side , lets create client application to invoke web service do the testing.To this right click on the project solution and add a windows application to the solutions give project name as "UserCredentialDemo"

On this project first t you need a button to invoke web service and rename caption of the button as "Check Me". and then add Custom security class on this project also. Because of when we send password to server we need encrypt in the client side.

Then we need add web reference to client application, to this you need right on click the client project then select Add Web Reference menu.after add web reference it like look like this.

Image Loading...


Let's write few line of code to access web service method.

Form1.cs
{codecitation class="brush: csharp; gutter: true;" width="650px"}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using UserCredentialWithServerDemo.DataServices;

namespace UserCredentialWithServerDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnCheckMe_Click(object sender, EventArgs e)
{
DataServices.DataServices service = new UserCredentialWithServerDemo.DataServices.DataServices();
service.Url = "http://localhost/UserCredentialWithSHInWebService/DataServices.asmx";
SoapUserAuthenticationHeader soapUserAuthenticationHeader=new UserCredentialWithServerDemo.DataServices.SoapUserAuthenticationHeader();
soapUserAuthenticationHeader.Username="test";
soapUserAuthenticationHeader.Token=new CustomSecutiry().Encrypt("pass");

service.SoapUserAuthenticationHeaderValue = soapUserAuthenticationHeader;
string [] data =new string []{"test1","test2"};
string message = service.Message(data);
MessageBox.Show(message, "Server message");

}
}
}

{/codecitation}

Just take yellow background code line before access web service method , we are setting user name and token value by SoapUserAuthenticationHeader .

Say if you are not pass user credential through the web service, you will get message (even you can throw like SoapHeadExeception As well) like you are not authorized person to access this web service.to test this just remove these lines in client code and build application and run.

when you click check me button you will get message like followings.

Image Loading...

Conclusion

That's all , now we have secured web service server and windows client.I hope this article will helpful and save time on your development progress.

Download client source code

Download Server source code


Thank you

RRaveen

 
Sign Up to vote for this article
 
About Author
 
RRaveen
Occupation-Software Engineer
Company-TGS
Member Type-Gold
Location-Singapore
Joined date-03 Jun 2009
Home Page-codegain.com
Blog Page-www.codegain.com
- B.Sc. degree in Computer Science. - 4+ years experience in Visual C#.net and VB.net - Obsessed in OOP style design and programming. - Designing and developing Network security tools. - Designing and developing a client/server application for sharing files among users in a way other than FTP protocol. - Designing and implementing GSM gateway applications and bulk messaging. - Windows Mobile and Symbian Programming - Having knowledge with ERP solutions
 
 
Other popularSectionarticles
    Another article of our series that talks about accessing URL shortening services programmatically. This article is talking about is.gd shortening service, how you can use it, and how to access it via your C#/VB.NET application.
    Published Date : 30/Aug/2010
    This is the first article of our series that talks about accessing URL shortening services programmatically. Here we introduce new concepts like the REST API. We also have a brief discussion of URL shortening services APIs and how you can access them. In addition, we are going to talk about .NET support for the REST API and tools and techniques available that would help us during our journey through the API. A working example built using C# and WinForms is available at the end of this a
    Published Date : 29/Aug/2010
    10 Rules to justify a true Web service
    Published Date : 16/Feb/2010
    Flex Communication with ASP.NET WebService
    Published Date : 16/Feb/2010
    Using the OneWay Web Service Attribute
    Published Date : 15/Feb/2010
Comments
There is no comments for this articles.
Leave a Reply
Title:
Display Name:
Email:
(not display in page for the security purphase)
Website:
Message:
Please refresh your screen using Ctrl+F5
If you can't read this number refresh your screen
Please input the anti-spam code that you can read in the image.
^ Scroll to Top