.NET与Axis的SOAPHeader
来源:互联网 发布:mimics软件 编辑:程序博客网 时间:2024/06/10 09:08
这两天做WSScore工程项目遇到一个关于Web Service身份认证的问题。当然,简单点做就是向SOAP添加SOAPHeader信息,在SOAP头里面放入身份认证信息。我这个WSScore是用.NET写的Web服务,然后通过从调用端传来的SOAP消息中加入相应的身份认证头信息,就可以让服务端轻松解析了。
虽然对于.NET的调用端可以方便的使用服务实例添加SOAPHeader对象实例到其中,但是,对于我的一个子系统——Axis调用端来说,就不会是这么简单的想添加个头信息,对方(.NET服务端)就能从[SOAPHeader("Credentials")]这种SOAPHeader属性中轻松解析出来的问题。
尽管在Axis调用端写入了头信息,但.NET服务端并没有将这个SOAP头传给SOAPHeader所指定的属性,这一点通过调试,跟踪一下就清楚地看到了,属性为null。究竟为什么,我目前找到相关资料能解释这点。但个人觉得,问题出在[SOAPHeader("xxxHeader")]这个属性赋值究竟是怎样的运行机制。
目前我想出个解决方案,下面就简单说说怎样让.NET读出Axis写的SOAPHeader的身份验证信息。
在.NET下,建立具有SOAPHeader的WebService
这里简单写一下.net调用端的SOAPHeader添加方式,以作为和Axis的比照。下面是C#编写的应用程序客户端,它可以调用Web服务。先在项目里引用服务。
WebReference.Service serivce = GetWebServiceReference("调用者", "密码");
private static Service GetWebServiceReference(string username, string password)
{
Service dataService = new Service();
CredentialSoapHeader header = new CredentialSoapHeader();
header.Username = username;
header.Password = password;
dataService.CredentialSoapHeaderValue = header;
dataService.Credentials = (System.Net.NetworkCredential)CredentialCache.DefaultCredentials;
return dataService;
}
通过这种方式,就完成了设定SOAPHeader,相对简便些。之后,就可以在应用程序里调用这个service的一些方法了。
下面,我们来看Axis的SOAPHeader怎样添加身份认证信息,使得能让前面的.NET Web服务可以访问SOAP头。拿个登陆的函数作为例子:
public int isLoginSuccessful(String studentID, String password){
try {
String endpoint= ".......";
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("http://www.wsscore.com/Login/SU","Login"));
call.addParameter("studentID",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);
call.addParameter("password",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);
call.setUseSOAPAction(true);
call.setSOAPActionURI("http://www.wsscore.com/Login/Rpc");
/*========================添加SOAPHeader方式==============================*/
String namespace = "http://www.wsscore.com/";
// 注意这里保持SOAP的标签一致CredentialSoapHeader,最好一致~不然就意义不大了~~
SOAPHeaderElement header = new SOAPHeaderElement(namespace,"CredentialSoapHeader");
header.setPrefix("");
javax.xml.soap.SOAPElement soapElement = header.addChildElement("Username");
soapElement.addTextNode("调用者");
soapElement = header.addChildElement("Password");
soapElement.addTextNode("密码");
call.addHeader(header);
/*========================================================================*/
int k = (Integer)call.invoke(new Object[]{studentID,password});
System.out.println( "result is " + k + ".");
return k;
}
catch (Exception e) {System.err.println(e.toString());}
return -1;
}
这样,就可以轻松的实现不论是从.NET的调用端,还是从Java的调用端,都可以提供具有身份验证的SOAPHeader了。
小结一下。.NET将Web服务的构建步骤简化对开发人员来说还是比较好的,不过就是简化太多的话,开发人员也都忘了问自己问什么这么做了。Axis是Aapache的开源Web Service架构,能让用户实现比较好用的Java平台上的Web服务。然而,目前的问题似乎仍是平台间的互通信并不如意,只是因为各自的实现方式不同,做同一件事情时,就存在交流障碍。当然,希望能早日看到SOA和Web Services的新成就,尤其这方便比较感兴趣的芸芸众生们~~为了迎接这一辉煌时刻的到来,努力奋斗啊!
我也马上要研究生实习了,希望不论以后自己做什么,都能保留一份让自己神清气爽的后花园~
虽然对于.NET的调用端可以方便的使用服务实例添加SOAPHeader对象实例到其中,但是,对于我的一个子系统——Axis调用端来说,就不会是这么简单的想添加个头信息,对方(.NET服务端)就能从[SOAPHeader("Credentials")]这种SOAPHeader属性中轻松解析出来的问题。
尽管在Axis调用端写入了头信息,但.NET服务端并没有将这个SOAP头传给SOAPHeader所指定的属性,这一点通过调试,跟踪一下就清楚地看到了,属性为null。究竟为什么,我目前找到相关资料能解释这点。但个人觉得,问题出在[SOAPHeader("xxxHeader")]这个属性赋值究竟是怎样的运行机制。
目前我想出个解决方案,下面就简单说说怎样让.NET读出Axis写的SOAPHeader的身份验证信息。
在.NET下,建立具有SOAPHeader的WebService
public class CredentialSoapHeader : SoapHeader
{
public string Username;
public string Password;
}
public class Service : System.Web.Services.WebService
{
public Service () {}
public CredentialSoapHeader Credentials; // 保存SOAP中验证身份的SOAPHeader
public SoapUnknownHeader[] unknownHeaders; // 保存Axis不能被.NET识别的SOAPHeader
[WebMethod]
[SoapHeader("Credentials")] // 对于.NET的调用端可以轻松获取SOAPHeader信息给Credential属性
[SoapHeader("unknownHeaders")] // 对于Axis的SOAPHeader,就将SOAPHeader赋给unknownHeaders属性
public string HelloWorld() {
this.VerifyCredential(this,flag); // 验证服务
return "Hello World";
}
private void VerifyCredential(Service s, int right) // 验证服务
{
if (s.Credentials == null && s.unknownHeaders != null) // 对于Axis的SOAPHeader,执行
{
foreach (SoapUnknownHeader header in s.unknownHeaders)
{
string str = header.Element.Name.ToString();
if (str.Equals("CredentialSoapHeader")) // 在Axis中仍要保持SOAPHeader的标签正确
{
// 获取用户名和密码,获取方式同读取XMLNode一样,方式随意
string username = header.Element.LastChild.PreviousSibling.InnerText.ToString();
string password = header.Element.LastChild.InnerText.ToString();
if (!Authenticate(username, password,right)) // 如果认证失败则抛异常
throw new SoapException("验证失败", SoapException.ClientFaultCode, "Security");
}
}
}
else // 对于.NET的调用端,执行这里
{
if (s.Credentials == null || s.Credentials.Username == null || s.Credentials.Password == null)
{
throw new SoapException("验证失败1", SoapException.ClientFaultCode, "Security");
}
if (!Authenticate(s.Credentials.Username, s.Credentials.Password, right))
throw new SoapException("验证失败2", SoapException.ClientFaultCode, "Security");
}
}
}
{
public string Username;
public string Password;
}
public class Service : System.Web.Services.WebService
{
public Service () {}
public CredentialSoapHeader Credentials; // 保存SOAP中验证身份的SOAPHeader
public SoapUnknownHeader[] unknownHeaders; // 保存Axis不能被.NET识别的SOAPHeader
[WebMethod]
[SoapHeader("Credentials")] // 对于.NET的调用端可以轻松获取SOAPHeader信息给Credential属性
[SoapHeader("unknownHeaders")] // 对于Axis的SOAPHeader,就将SOAPHeader赋给unknownHeaders属性
public string HelloWorld() {
this.VerifyCredential(this,flag); // 验证服务
return "Hello World";
}
private void VerifyCredential(Service s, int right) // 验证服务
{
if (s.Credentials == null && s.unknownHeaders != null) // 对于Axis的SOAPHeader,执行
{
foreach (SoapUnknownHeader header in s.unknownHeaders)
{
string str = header.Element.Name.ToString();
if (str.Equals("CredentialSoapHeader")) // 在Axis中仍要保持SOAPHeader的标签正确
{
// 获取用户名和密码,获取方式同读取XMLNode一样,方式随意
string username = header.Element.LastChild.PreviousSibling.InnerText.ToString();
string password = header.Element.LastChild.InnerText.ToString();
if (!Authenticate(username, password,right)) // 如果认证失败则抛异常
throw new SoapException("验证失败", SoapException.ClientFaultCode, "Security");
}
}
}
else // 对于.NET的调用端,执行这里
{
if (s.Credentials == null || s.Credentials.Username == null || s.Credentials.Password == null)
{
throw new SoapException("验证失败1", SoapException.ClientFaultCode, "Security");
}
if (!Authenticate(s.Credentials.Username, s.Credentials.Password, right))
throw new SoapException("验证失败2", SoapException.ClientFaultCode, "Security");
}
}
}
这里简单写一下.net调用端的SOAPHeader添加方式,以作为和Axis的比照。下面是C#编写的应用程序客户端,它可以调用Web服务。先在项目里引用服务。
WebReference.Service serivce = GetWebServiceReference("调用者", "密码");
private static Service GetWebServiceReference(string username, string password)
{
Service dataService = new Service();
CredentialSoapHeader header = new CredentialSoapHeader();
header.Username = username;
header.Password = password;
dataService.CredentialSoapHeaderValue = header;
dataService.Credentials = (System.Net.NetworkCredential)CredentialCache.DefaultCredentials;
return dataService;
}
通过这种方式,就完成了设定SOAPHeader,相对简便些。之后,就可以在应用程序里调用这个service的一些方法了。
下面,我们来看Axis的SOAPHeader怎样添加身份认证信息,使得能让前面的.NET Web服务可以访问SOAP头。拿个登陆的函数作为例子:
public int isLoginSuccessful(String studentID, String password){
try {
String endpoint= ".......";
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("http://www.wsscore.com/Login/SU","Login"));
call.addParameter("studentID",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);
call.addParameter("password",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);
call.setUseSOAPAction(true);
call.setSOAPActionURI("http://www.wsscore.com/Login/Rpc");
/*========================添加SOAPHeader方式==============================*/
String namespace = "http://www.wsscore.com/";
// 注意这里保持SOAP的标签一致CredentialSoapHeader,最好一致~不然就意义不大了~~
SOAPHeaderElement header = new SOAPHeaderElement(namespace,"CredentialSoapHeader");
header.setPrefix("");
javax.xml.soap.SOAPElement soapElement = header.addChildElement("Username");
soapElement.addTextNode("调用者");
soapElement = header.addChildElement("Password");
soapElement.addTextNode("密码");
call.addHeader(header);
/*========================================================================*/
int k = (Integer)call.invoke(new Object[]{studentID,password});
System.out.println( "result is " + k + ".");
return k;
}
catch (Exception e) {System.err.println(e.toString());}
return -1;
}
这样,就可以轻松的实现不论是从.NET的调用端,还是从Java的调用端,都可以提供具有身份验证的SOAPHeader了。
小结一下。.NET将Web服务的构建步骤简化对开发人员来说还是比较好的,不过就是简化太多的话,开发人员也都忘了问自己问什么这么做了。Axis是Aapache的开源Web Service架构,能让用户实现比较好用的Java平台上的Web服务。然而,目前的问题似乎仍是平台间的互通信并不如意,只是因为各自的实现方式不同,做同一件事情时,就存在交流障碍。当然,希望能早日看到SOA和Web Services的新成就,尤其这方便比较感兴趣的芸芸众生们~~为了迎接这一辉煌时刻的到来,努力奋斗啊!
我也马上要研究生实习了,希望不论以后自己做什么,都能保留一份让自己神清气爽的后花园~
- .NET与Axis的SOAPHeader
- axis设置SoapHeader
- axis 添加 soapHeader 请求
- AXIS报文头SOAPHEADER认证
- .net调用含SoapHeader的xfire服务
- .NET WS客户端与Axis服务端的互操作问题
- SoapHeader 的作用是什么
- spring与axis的整合
- Axis与XFire的比较
- Axis与Spring的集成
- WebService基于SoapHeader实现安全认证[webservice][.net][安全][soapheader]
- NET WebService客户端与Axis(Java WebSerivce)服务端的互操作问题
- [转帖]Java与.NET 的Web Services相互调用(axis)
- axis,axis2调用.net的webservice
- axis,axis2调用.net的webservice
- ASP.NET调用JAVA的CXF生成的Webservice,并带有Soapheader验证的解决方案
- asp.net中用soapheader作验证的使用步骤: 很简单
- .net调用java xfire发布的webservice封装soapheader头信息
- ActiveReport for net WebViewer 设置zoom
- 这一早,我学会了凌波微步
- HP IBM HDD AND MEMORY
- 消息队列(Message Queue)简介及其使用(转)
- 关于java作用域
- .NET与Axis的SOAPHeader
- JavaScript 小知识记录(长期更新)
- 2007年4月12日 阴 小雨
- C++中的文件输入/输出
- My Hometown
- gcc研究笔记(二)cp和cpplib的接口
- 小程序--更改Windows“开始”菜单名称
- java中文字符串按拼音排序 代码
- Webwork使用Freemarker入门实例