本文转自:http://www.codeproject.com/Articles/9348/Web-Service-Authentication

Introduction

This is a simple mechanism to authenticate users to a Web Service, using a Time Token and MD5 Hashing to encrypt password.

Background

In CodeProject, you can find at least two others' mechanism to authenticate users to a Web Service. Dan_P wroteAuthentication for Web Services as a Simple authentication for web services using SOAP headers. But the username and password are sent in clear text and there is no encryption for the data. HENDRIK R. is the author of An introduction to Web Service Security using WSE, that is really a complete solution, but too much complicated for my purposes. The username is sent in clear text, but it is possible to use Password Digest to encrypt the password. The data are encrypted using XML Encryption specification to encrypt portions of the SOAP messages.

My solution is something in the middle of the above two. The username is sent in clear text, but I use MD5 to encrypt the password. I do not need to send sensitive data, so the data returned by the Web Service is not encrypted.

Using the Code

The basic idea is to send UserName and Password from the client to the Web Service using MD5 Hash Code as encryption system. In this way, the password never travels in clear over the network. The Web Service retrieves the user password from a DB or anything else and uses the same MD5 algorithm to test if the password is correct. To be sure that if someone intercepts the Hash, this can be used to authenticate in a later time, I added a timestamp before hashing the Key string. Last, as we are not always on the same server and/or the client clock may be in a different Time Zone or simply not synchronized, I added the possibility to request a Token containing the time mark to the server.

I provided a sample in ASP.NET C# for the client side, but it is possible to use any language: ASP classical JScript or VBScript, PHP, Python, etc. Anyway, on the client side we need to build up the Key using UserNamePassword and the hashed timestamp Token previously got from the same Web Service. We can then call the Service and we will get the answer (or an authentication failure warning) that is displayed on the web page.

 Collapse | Copy Code
private void ButtonUseToken_Click(object sender, System.EventArgs e)
{
string ret;
string UserName, Password, ServiceName, Token;
string Key, ToHash; UserName=this.TextBoxUserName.Text;
Password=this.TextBoxPwd.Text;
ServiceName=this.TextBoxService.Text;
Token=this.TextBoxToken.Text;
ToHash=UserName.ToUpper()+"|"+Password+"|"+Token;
Key=Hash(ToHash)+"|"+UserName; ServicePointReference.ServicePoint Authenticate =
new ServicePointReference.ServicePoint();
ret=Authenticate.UseService(Key, ServiceName);
this.ServResponse.Text=ret;
}

The MD5 Hash procedure is very simple in C#; this one was written by Vasudevan Deepak Kumar in Securing Web Accounts.

 Collapse | Copy Code
private string Hash(string ToHash)
{
// First we need to convert the string into bytes,
// which means using a text encoder.
Encoder enc = System.Text.Encoding.ASCII.GetEncoder(); // Create a buffer large enough to hold the string
byte[] data = new byte[ToHash.Length];
enc.GetBytes(ToHash.ToCharArray(), 0, ToHash.Length, data, 0, true); // This is one implementation of the abstract class MD5.
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(data); return BitConverter.ToString(result).Replace("-", "").ToLower();
}

On Web Service server side, I implemented just three Web Methods:

GetToken is used to get the Time-marked token. The token you get this way is intended to be used in the basicAuthenticate method, or in the UseService that can also verify the access rights for the users authenticated to the requested service. The core of the system is implemented by TestHash. Here the password is hard-coded, but in the sample provided, you have also the code to get it from a database:

 Collapse | Copy Code
private bool TestHash (string HashStr,
string UserName, int minutes, string ServiceName)
{
string Pwd, ToHash;
string sResult, sResultT, sResultToken;
try
{
// JUST FOR TEST: the password is hard-coded:
Pwd="SeCrEt"; DateTime dt = DateTime.Now;
System.TimeSpan minute = new System.TimeSpan(0,0,minutes,0,0);
dt = dt-minute;
//before hashing we have:
//USERNAME|PassWord|YYYYMMDD|HHMM
ToHash=UserName.ToUpper()+"|"+Pwd+"|"+dt.ToString("yyyyMMdd")+
"|"+dt.ToString("HHmm");
sResult = Hash(ToHash);
//TokenWeGotBefore
ToHash=dt.ToString("yyyyMMdd")+"|"+dt.ToString("HHmm");
sResultToken = Hash(ToHash);
//USERNAME|PassWord|TokenWeGotBefore
ToHash=UserName.ToUpper()+"|"+Pwd+"|"+sResultToken;
sResultT = Hash(ToHash); if ((sResult==HashStr) || (sResultT==HashStr))
return true;
else
if (minutes==0) // allowed max 2 minutes - 1
// second to call web service
return TestHash (HashStr, UserName, 1, ServiceName);
else
return false;
}
catch
{
return false;
}
}

To request a hashed time-stamped Token to the Web Service, the method is:

 Collapse | Copy Code
[WebMethod]
public string GetToken ()
{
string ToHash, sResult;
DateTime dt = DateTime.Now;
ToHash=dt.ToString("yyyyMMdd")+"|"+dt.ToString("HHmm");
sResult = Hash(ToHash);
return sResult;
}

The method that checks the user authentication is also kept very simple; in a real application you normally need to access a database to check the authentication level and may need to return some data to the caller:

 Collapse | Copy Code
[WebMethod]
public string UseService (string Key, string ServiceName)
{
string [] HashArray;
string UserName, level; // Key string: HASH|User|OptionalData
HashArray=Key.Split('|');
level = "-1"; //default level if (TestHash(HashArray[0], HashArray[1], 0, ServiceName))
{
try
{
UserName=HashArray[1];
// JUST FOR TEST: the User authentication level is hard-coded
// but may/should be retrieved from a DataBase
switch (UserName)
{
case "MyUserName":
level="1";
break;
case "OtherUser":
level="2";
break;
default:
level="-1";
break;
}
if (level=="1") return "YOU ARE AUTHORIZED";
}
catch (Exception exc)
{
return "Authentication failure: " + exc.ToString();
}
}
return "Authentication failure";
}

Points of Interest

TestHash checks to see if the Hash contains a timestamp or an already-hashed token, and calls itself once again in case of failure: if someone is calling the service, let's say, at 11:34:58 the Key is valid from 11:34:00 until 11:35:59, that is during two minutes minus one second.

The client side may be implemented in any language: ASP classical, JScript or VBScript, PHP, Python, etc. I have the intention to post this code too next time...

[转]Web Service Authentication的更多相关文章

  1. Error in WCF client consuming Axis 2 web service with WS-Security UsernameToken PasswordDigest authentication scheme

    13down votefavorite 6 I have a WCF client connecting to a Java based Axis2 web service (outside my c ...

  2. 关于WEB Service&WCF&WebApi实现身份验证之WebApi篇

    之前先后总结并发表了关于WEB Service.WCF身份验证相关文章,如下: 关于WEB Service&WCF&WebApi实现身份验证之WEB Service篇. 关于WEB S ...

  3. 关于WEB Service&WCF&WebApi实现身份验证之WEB Service篇

    在这个WEB API横行的时代,讲WEB Service技术却实显得有些过时了,过时的技术并不代表无用武之地,有些地方也还是可以继续用他的,我之所以会讲解WEB Service,源于我最近面试时被问到 ...

  4. Web Service 的工作原理

    Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...

  5. Web Service实现分布式服务的基本原理

    简单的说, 就是客户端根据WSDL 生成 SOAP 的请求消息, 通过 HTTP 传输方式(也可以是其它传输方式, 如 FTP 或STMP 等,目前 HTTP 传输方式已经成为 J2EE Web Se ...

  6. Summary of Amazon Marketplace Web Service

    Overview Here I want to summarize Amazon marketplace web service (MWS or AMWS) that can be used for ...

  7. wsse:InvalidSecurity Error When Testing FND_PROFILE Web Service in Oracle Applications R 12.1.2 from SOAP UI (Doc ID 1314946.1)

    wsse:InvalidSecurity Error When Testing FND_PROFILE Web Service in Oracle Applications R 12.1.2 from ...

  8. Web Service工作原理

    Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...

  9. web service接口测试工具选型

    1  简介 1.1   范围 1.2   目的 本文档用于指导测试部进行接口测试. 2013-03-11磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.com ...

随机推荐

  1. Win7下虚拟机个人使用小结:Virtual PC,VMware和VirtualBox

    想来用了很多年的虚拟机了,换了Win7之后,种种原因又需要使用虚拟机,这里就简单介绍和比较一下. 点击小图看大图. Virtual PC: 如果想做Windows虚拟机的话,Virtual PC在之前 ...

  2. Greedy:Yogurt factory(POJ 2393)

    酸奶工厂 题目大意:酸奶工厂每个星期都要制造酸奶,成本每单位x,然后每个星期要生产y,然后酸奶厂有个巨大的储存室,可以无限储存酸奶,而且酸奶的品质不会变坏,每天储存要每单位花费S,求最小的成本. 简直 ...

  3. Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述

    概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...

  4. atom 震动特效

    1.下载atom 2.配置环境变量 3.运行apm install activate-power-mode 4.打开Atom激活(control+alt+o(是o不是零)) 注:新标签若没效果可以ct ...

  5. eclipse 优化提速

    1.windows–>perferences–>general–>startup and shutdown关掉没用的启动项: WTP :一个跟myeclipse差不多的东西,主要差别 ...

  6. 爱改名的小融 2(codevs 3149)

    3149 爱改名的小融 2  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description Wikioi上有个人 ...

  7. 谈谈异步加载JavaScript

    前言 关于JavaScript脚本加载的问题,相信大家碰到很多.主要在几个点—— 1> 同步脚本和异步脚本带来的文件加载.文件依赖及执行顺序问题 2> 同步脚本和异步脚本带来的性能优化问题 ...

  8. javascript reduce map函数方法

    retduce: 对数组中的所有元素调用指定的回调函数.该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供. 语法     array1.reduce(callbackfn ...

  9. MyISAM InnoDB 区别

    MyISAM 和 InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处 ...

  10. 面向服务的体系结构(SOA)——(5)关于MEP(Message Exchange Patterns)

    SOA中的MEP和JavaEE中的JMS类似,当然了就应该是类似的,因为都是关于消息方面的.一个是对系统架构当中消息的解决思路,一个是针对Java平台中的消息的具体解决办法(严格说不是具体的,只是提供 ...