.net C# 调用 XFire发布的Webservice 安全访问控制
2009-12-31 16:13
489 查看
最近接触到的项目要使用.net调用xfire发布webservice,在网上找了很多方法,遇到一些“牛人”粘贴了千篇一律的代码,看着头痛,但实际的问题并没有解决,在一次调试过程中发现服务端的安全处理Handler是有状态的,于是想了个办法让服务器端保存客户端调用的认证信息,认证一次后并不再需要对身份进行多次认证
这里和大家分享一下具体的代码
关于使用Xfire开发Webservice大家可以去网上搜搜,都写的很好,图文并茂,
我在这里强调的是跨平台的安全调用和状态保留,本文将阐述如何使用SOAP Header传递认证信息并且保存客户端的调用状态
这是.net 生成代理类的使用wsdl.exe工具 配置文档如下
服务器上我们添加验证方法
稍微解释下此段代码
当web服务器启动的时候,比如tomcat启动的时候,该类将被实列化,生命周期直到tomcat关闭的时候结束
服务器services.xml
配置如下
.net客户端调用的时候添加一个类
然后再生成的代理类里面添加
在生成的代理类的调用方法上再添加如下代码
在调用该方法时候,验证信息将被加入soap header中
调用采用
纠正一点,其实Java与C#通过Webservice通信的安全控制还是可以用session来控制的,只是客户端需要保存一cookie,C#提供了一个cookieContainer来为我们保存Session
这里和大家分享一下具体的代码
关于使用Xfire开发Webservice大家可以去网上搜搜,都写的很好,图文并茂,
我在这里强调的是跨平台的安全调用和状态保留,本文将阐述如何使用SOAP Header传递认证信息并且保存客户端的调用状态
这是.net 生成代理类的使用wsdl.exe工具 配置文档如下
<?xml version="1.0" encoding="utf-8"?> <wsdlParameters xmlns="http://microsoft.com/webReference/"> <nologo>true</nologo> <parsableerrors>true</parsableerrors> <sharetypes>true</sharetypes> <namespace>ConsoleApplication1</namespace> <documents> <document>http://localhost:8080/v2/services/KillService?wsdl</document> </documents> </wsdlParameters>
服务器上我们添加验证方法
package com; /** * @author Zhang Qi * @CreateTime 2009-12-30 * **/ import java.util.Date; import java.util.HashMap; import java.util.Iterator; import org.codehaus.xfire.MessageContext; import org.codehaus.xfire.fault.XFireFault; import org.codehaus.xfire.handler.AbstractHandler; import org.codehaus.xfire.transport.http.XFireServletController; import org.jdom.Element; import org.jdom.Namespace; public class AuthenticationHandler extends AbstractHandler implements Runnable { public AuthenticationHandler() { // 该线程检查用户登录是否超时 new Thread(this).start(); } // 定义hashMap 存储用户验证信息,key经过验证的用户IP,或者客户端特定信息 HashMap<String, String> hash = new HashMap<String, String>(); // 当某个客户端登录成功后,纪录登录的时间,key 为经过验证的用户IP,或者客户端的特定信息 HashMap<String, Date> createHashDate = new HashMap<String, Date>(); private final static Namespace TOKEN_NS = Namespace .getNamespace("demoService"); // 统计当前服务访问的人数 Integer count = 0; public void invoke(MessageContext context) throws Exception { // 假如hash中存在用户验证信息,则直接跳出该函数,不再进行验证 if (hash.containsKey(XFireServletController.getRequest() .getRemoteAddr())) { return; } // 得到客户soap header 对象 Element header = context.getInMessage().getHeader(); if (header == null) { throw new XFireFault( "Request must include company authentication token1.", XFireFault.SENDER); } // 得到认证令牌 Element token = header.getChild("AuthenticationToken", TOKEN_NS); if (token == null) { throw new XFireFault("Request must include authentication token.", XFireFault.SENDER); } Element name = token.getChild("name", TOKEN_NS); Element password = token.getChild("password", TOKEN_NS); if (name == null || password == null) { throw new XFireFault("AuthenticationToken Error,name or password is null", XFireFault.SENDER); } String nameValue = name.getValue(); String passwordValue = password.getValue(); if (nameValue == null||passwordValue==null) { throw new XFireFault("name or password's value is null.", XFireFault.SENDER); } try { //进行服务器端验证 if (nameValue.equals("admin") && passwordValue.equals("admin")) { System.out.println("登录成功!登录时间:" + new Date()); System.out.println("当前人数:" + (++count)); hash.put(XFireServletController.getRequest().getRemoteAddr(), XFireServletController.getRequest().getRemoteAddr()); createHashDate.put(XFireServletController.getRequest() .getRemoteAddr(), new Date()); } else { System.out.println("fail login"); throw new Exception("Login fail"); } } catch (Exception e) { throw new XFireFault("Authentication Failed.", XFireFault.SENDER); } } public void run() { service(); } public synchronized void service() { while (true) { try { /** * 取出用户登录时间与当前时间进行对比 * 如果当前时间与用户登录时间之差大于系统设置的某个时间,则将用户登录信息清除 * **/ for (Iterator<String> keys = hash.keySet().iterator(); keys.hasNext();) { Date now = new Date(); String key = keys.next(); long time = now.getTime() - createHashDate.get(key).getTime(); if (time > 20*30 * 1000) { System.out.println(now); System.out.println(createHashDate.get(key)); synchronized (hash) { hash.remove(key); } synchronized (count) { count--; } } } //每10秒钟进行一次用户登录信息检测 Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
稍微解释下此段代码
当web服务器启动的时候,比如tomcat启动的时候,该类将被实列化,生命周期直到tomcat关闭的时候结束
服务器services.xml
配置如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xfire.codehaus.org/config/1.0"> <service xmlns="http://xfire.codehaus.org/config/1.0"> <name>demoService</name> <namespace>demoService</namespace> <serviceClass>com.kiloway.webservice.demo.Iservice</serviceClass> <implementationClass>com.kiloway.webservice.demo.serviceImpl</implementationClass> <inHandlers> <handler handlerClass="com.kiloway.webservice.demo.AuthenticationHandler"></handler> </inHandlers> <mce:style><!-- wrapped --></mce:style><style mce_bogus="1">wrapped</style> <use>literal</use> <scope>application</scope> </service> </beans>
.net客户端调用的时候添加一个类
客户端采用.net调用 添加客户端的AuthenticationToken 具体代码如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Services; using System.Web.Services.Protocols; namespace ConsoleApplication1 { [System.Serializable] [System.Xml.Serialization.XmlType(Namespace = "demoService")] [System.Xml.Serialization.XmlRoot(Namespace = "demoService", IsNullable = false)] public class AuthenticationToken : SoapHeader { public string name = null; public string password = null; } }
然后再生成的代理类里面添加
public AuthenticationToken SoapHeader = new AuthenticationToken();
在生成的代理类的调用方法上再添加如下代码
[SoapHeader("SoapHeader")]
在调用该方法时候,验证信息将被加入soap header中
调用采用
demoService demo = new demoService(); while (true) { demo.SoapHeader.name = "admin"; demo.SoapHeader.password = "admin"; System.Console.WriteLine(demo.sum(1, 23)); System.Console.WriteLine(demo.example("Hello,Kity")); }
纠正一点,其实Java与C#通过Webservice通信的安全控制还是可以用session来控制的,只是客户端需要保存一cookie,C#提供了一个cookieContainer来为我们保存Session
相关文章推荐
- .net C# 调用 XFire发布的Webservice 安全访问控制
- ASP.NET中Webservice安全 实现访问权限控制
- C#.net访问web URL并处理返回值 && 不加web引用调用webservice
- 使用.net调用xfire发布webservice的统一安全认证
- 20101109 学习记录: C#.net访问web URL并处理返回值 && 不加web引用调用webservice
- ASP.NET中Webservice安全 实现访问权限控制
- 使用session控制 XFire 发布的Webservice 并且由.net调用
- java 调用xfire发布的webservice,通过传输byte[]上传图片,byte[]丢失、截断
- JAVA axis调用Asp.net发布WebService返回XmlNode数据类型
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- c#调用带有安全认证的java webservice
- 使用xfire编写webservice,并通过C#调用
- 发布NBearLite v1.0.0 beta - 全面支持SqlServer,Oracle,MySql,PostgreSql数据库存储过程调用代码生成(C#/VB.NET)
- 开发,配置,调用-三步走构建简单的asp.net webservice(C#)-适合初学者阅读
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- 使用C#创建webservice及三种调用方式 (ASP.NETweb编程常用到的27个函数集)
- 在与sap系统集成时遇到的问题.sap系统发布一webservice,java(xfire)作为客户端调用,调用时抛出如下异常: Wrong Content-Type and empty HTTP-Body received: ("HTTP Code 20
- 【工作记录0022】C#(.NET)调用Java开发的WebService(wsdl),客户端传递非string类型参数(int,double,bool等),而服务端无法获取到参数值的解决方案
- .NET C#动态调用WebService