• WSE2.0的BUG?!


    在帮客户写JAVA客户端访问.NET实现的Web service的示例代码发现了一个有趣的问题。为有保障安全性,使用了wse2.0 sp2的ws-security,自己实现了UsernameTokenManager的AuthenticateToken方法。当从本机的浏览器访问该服务时,返回HTTP 500错误。写了一个winform客户端的测试代码,当使用不正确的用户名与密码时,服务抛出错误,使用正确的用户名与密码时,服务返回正确的结果,一切看起来都很正常。但当使用java的客户端访问时,无论使用什么样的客户名与密码,服务均能正确返回结果。不知道是否WSE2.0的bug还是设置的问题,让jeet很是郁闷。
    示例代码如下:
    1、WEB service代码:

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Tokens;

    namespace WebTest
    {
        
    /// <summary>
        
    /// SumService 的摘要说明。
        
    /// </summary>

        public class SumService : System.Web.Services.WebService
        
    {
            
    public SumService()
            
    {
                
    //CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的
                InitializeComponent();
            }


            
    组件设计器生成的代码

            
    // WEB 服务示例
            
    // HelloWorld() 示例服务返回字符串 Hello World
            
    // 若要生成,请取消注释下列行,然后保存并生成项目
            
    // 若要测试此 Web 服务,请按 F5 键
    //
            [WebMethod]
            
    public string HelloWorld()
            
    {
                SoapContext requestContext
    =RequestSoapContext.Current;
                
    if(requestContext==null)
                    
    throw new ApplicationException("Only soap request are permitted.");
                
    return "Hello World.";
            }

            [SoapRpcMethod(Action
    ="http://www.gds-china.com/Rpc",RequestNamespace="http://www.gds-china.com/SU",ResponseNamespace="http://www.gds-china.com/SU")]
            [WebMethod]
            
    public int IntAdd(int a,int b)
            
    {
                SoapContext requestContext
    =RequestSoapContext.Current;
                
                
    if(requestContext==null)
                    
    throw new ApplicationException("Only soap request are permitted.");
                

                
    return a+b;
            }


            
        }

        }


    2、实现UsernameTokenManager
    using System;
    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Tokens;
    using System.Security;
    using System.Security.Permissions;

    namespace WebTest
    {
        
    /// <summary>
        
    /// CustomUsernameTokenManager 的摘要说明。
        
    /// </summary>

        [SecurityPermission(SecurityAction.Demand,
             Flags
    = SecurityPermissionFlag.UnmanagedCode)]

        
    public class CustomUsernameTokenManager:UsernameTokenManager
        
    {
            
    public CustomUsernameTokenManager()
            
    {
                
    //
                
    // TODO: 在此处添加构造函数逻辑
                
    //
            }


            
    protected override string AuthenticateToken(UsernameToken token)
            
    {
                
    if(token==null)
                    
    throw new ArgumentNullException();
                
    if(token.Username=="username")
                    
    return "password";
                
    else
                    
    return "love";
                
    //                byte[] encodedUsername=System.Text.Encoding.UTF8.GetBytes(token.Username);
    //                if(System.Text.Encoding.UTF8.GetString(encodedUsername)=="username")
    //                    return "password";
    //            else
    //                    return "love";

            }


        }

    }


    3、Web service的web.config配置
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      
    <configSections>
        
    <section name="microsoft.web.services2" type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      
    </configSections>
      
    <system.web>
        
    <webServices>
          
    <protocols>
            
    <remove name="HttpGet" />
            
    <remove name="HttpPost" />
          
    </protocols>
          
    <soapExtensionTypes>
            
    <add type="Microsoft.Web.Services2.WebServicesExtension, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="1" group="0" />
          
    </soapExtensionTypes>
        
    </webServices>
        
    <!--  动态调试编译
              设置 compilation debug="true" 以启用 ASPX 调试。否则,将此值设置为
              false 将提高此应用程序的运行时性能。
              设置 compilation debug="true" 以将调试符号(.pdb 信息)
              插入到编译页中。因为这将创建执行起来
              较慢的大文件,所以应该只在调试时将此值设置为 true,而在所有其他时候都设置为
              false。有关更多信息,请参考有关
              调试 ASP.NET 文件的文档。
        
    -->
        
    <compilation defaultLanguage="c#" debug="true" />
        
    <!--  自定义错误信息
              设置 customErrors mode="On" 或 "RemoteOnly" 以启用自定义错误信息,或设置为 "Off" 以禁用自定义错误信息。 
              为每个要处理的错误添加 <error> 标记。

              "On" 始终显示自定义(友好的)信息。
              "Off" 始终显示详细的 ASP.NET 错误信息。
              "RemoteOnly" 只对不在本地 Web 服务器上运行的
               用户显示自定义(友好的)信息。出于安全目的,建议使用此设置,以便 
               不向远程客户端显示应用程序的详细信息。
        
    -->
        
    <customErrors mode="RemoteOnly" />
        
    <identity impersonate="true" />
        
    <!--  身份验证 
              此节设置应用程序的身份验证策略。可能的模式是 "Windows"、 
              "Forms"、 "Passport" 和 "None"

              "None" 不执行身份验证。 
              "Windows" IIS 根据应用程序的设置执行身份验证 
                (基本、简要或集成 Windows)。在 IIS 中必须禁用匿名访问。
              "Forms" 您为用户提供一个输入凭据的自定义窗体(Web 页),然后 
               在您的应用程序中验证他们的身份。用户凭据标记存储在 Cookie 中。
              "Passport" 身份验证是通过 Microsoft 的集中身份验证服务执行的,
               它为成员站点提供单独登录和核心配置文件服务。
        
    -->
        
    <authentication mode="Windows" />
        
    <!--  授权 
               此节设置应用程序的授权策略。可以允许或拒绝不同的用户或角色访问
              应用程序资源。通配符: "*" 表示任何人,"?" 表示匿名
              (未经身份验证的)用户。
        
    -->
        
    <authorization>
          
    <allow users="*" />
          
    <!-- 允许所有用户 -->
          
    <!--  <allow     users="[逗号分隔的用户列表]"
                                 roles="[逗号分隔的角色列表]"/>
                      <deny      users="[逗号分隔的用户列表]"
                                 roles="[逗号分隔的角色列表]"/>
                
    -->
        
    </authorization>
        
    <!--  应用程序级别跟踪记录
              应用程序级别跟踪为应用程序中的每一页启用跟踪日志输出。
              设置 trace enabled="true" 可以启用应用程序跟踪记录。如果 pageOutput="true",则
              在每一页的底部显示跟踪信息。否则,可以通过浏览 Web 应用程序
               根目录中的 "trace.axd" 页来查看
              应用程序跟踪日志。
        
    -->
        
    <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
        
    <!--  会话状态设置
              默认情况下,ASP.NET 使用 Cookie 来标识哪些请求属于特定的会话。
              如果 Cookie 不可用,则可以通过将会话标识符添加到 URL 来跟踪会话。
             若要禁用 Cookie,请设置 sessionState cookieless="true"。
        
    -->
        
    <sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
        
    <!--  全球化
              此节设置应用程序的全球化设置。
        
    -->
        
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
      
    </system.web>
      
    <microsoft.web.services2>
        
    <diagnostics>
          
    <trace enabled="true" input="InputTrace.webinfo" output="OutputTrace.webinfo" />
          
    <detailedErrors enabled="false" />
        
    </diagnostics>
        
    <security>
            
    <securityTokenManager type="WebTest.CustomUsernameTokenManager,WebTest" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" qname="wsse:UsernameToken" />
        
    </security>
      
    </microsoft.web.services2>
    </configuration>

    4、试验的.net客户端代码
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Tokens;
    using GDS.Ldap;
    using System.Text;

    namespace WSEClientTest
    {
        
    /// <summary>
        
    /// Form1 的摘要说明。
        
    /// </summary>

        public class Form1 : System.Windows.Forms.Form
        
    {
            
    private System.Windows.Forms.Button button1;
            
            
    /// <summary>
            
    /// 必需的设计器变量。
            
    /// </summary>

            private System.ComponentModel.Container components = null;

            
    public Form1()
            
    {
                
    //
                
    // Windows 窗体设计器支持所必需的
                
    //
                InitializeComponent();

                
    //
                
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
                
    //
            }


            
    /// <summary>
            
    /// 清理所有正在使用的资源。
            
    /// </summary>

            protected override void Dispose( bool disposing )
            
    {
                
    if( disposing )
                
    {
                    
    if (components != null
                    
    {
                        components.Dispose();
                    }

                }

                
    base.Dispose( disposing );
            }


            
    Windows 窗体设计器生成的代码

            
    /// <summary>
            
    /// 应用程序的主入口点。
            
    /// </summary>

            [STAThread]
            
    static void Main() 
            
    {
                Application.Run(
    new Form1());
            }


            
    private void button1_Click(object sender, System.EventArgs e)
            
    {
                UsernameToken token
    =new UsernameToken("username","password1",PasswordOption.SendPlainText);
                
    try
                
    {
                    localhost.SumServiceWse serviceProxy
    =new localhost.SumServiceWse();
                    SoapContext requestContext
    =serviceProxy.RequestSoapContext;
                    requestContext.Security.Timestamp.TtlInSeconds
    =60;
                    requestContext.Security.Tokens.Add(token);
                    
                    requestContext.Security.Elements.Add(
    new MessageSignature(token));
                    
                    
    int sum=serviceProxy.IntAdd(3,5);
                    MessageBox.Show(sum.ToString());

                }

                
    catch (System.Web.Services.Protocols.SoapException se) 
                
    {
                    MessageBox.Show(se.ToString());
                }

                
    catch (Exception ex) 
                
    {
                    MessageBox.Show(ex.ToString());
                    
    return;
                }

            
            }


        
            }

        }




    5、JAVA的客户端代码,使用axis-wsse(可从http://sourceforge.net/projects/axis-wsse/得到)
    /*
     * Created on 2005-2-26
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */
    package WSEClient;

    import net.vitale.filippo.axis.handlers.
    *;
    import org.apache.axis.client.
    *;
    import javax.xml.namespace.
    *;

    /**
     * @author Jeet
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */
    public class TestService
    {

        static String usernameS 
    = null
        static String passwordS 
    = null

        public static 
    void main(String[] args)
        {
            
    try { 
                Integer i 
    = new Integer(5); 
                Integer j 
    = new Integer(2); 
                String endpoint
    ="http://localhost/WebTest/SumService.asmx"
                Service service 
    = new Service(); 
                Call call 
    = (Call)service.createCall(); 
                call.setTargetEndpointAddress(
    new java.net.URL(endpoint)); 
                call.setOperationName(
    new QName("http://www.gds-china.com/SU","IntAdd")); 
                call.addParameter(
    "a",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN); 
                call.addParameter(
    "b",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN); 
                call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT); 
    //            call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
                call.setUseSOAPAction(true); 
                call.setSOAPActionURI(
    "http://www.gds-china.com/Rpc"); 
                
    //add a user token 
                usernameS="1234";
                passwordS 
    = "password"
                call.setUsername(usernameS); 
                call.setPassword(passwordS); 
        
                call.setProperty(WsseClientHandler.PASSWORD_OPTION, WsseClientHandler.PASSWORD_DIGEST_WITH_NONCE); 
                call.setClientHandlers(
    new WsseClientHandler(), null); 
                Integer k 
    = (Integer)call.invoke(new Object[]{i,j}); 
                System.out.println( 
    "result is " + k.toString() + "."); 
    //            Vector inputs = new Vector();
    //
                String s=(String)call.invoke(inputs.toArray());
    //
                System.out.println("result is "+s+ ".");
                      
               } 
               
    catch (org.apache.axis.AxisFault e) 
               { 
                
    if (e.getFaultCode().toString() .equals("{http://schemas.xmlsoap.org/ws/2002/07/secext}FailedAuthentication")) 
                 System.err.println(
    "The usernameToken and password aren't right! "); 
                
    else { 
                       System.err.println(e.getFaultCode().toString()); 
                } 
               } 
               
    catch(Exception e) 
               { 
                System.err.println(e.toString()) ; 
               } 
              } 
          } 


  • 相关阅读:
    Membership和Role Providers
    浏览器兼容手册
    手机开发与测试的Firefox插件:User Agent Switcher
    控制input输入框的高度
    纯 CSS3 打造的按钮实例
    CSS对各个浏览器兼容
    网页配色的天然范儿
    Jquery的each里面用return false代替break; return ture 代替continue
    li标签float:left,IE6中第二行会空缺一块,ie8和FF正常,怎么解决?
    用XMLHTTP实现无刷新的与server通信
  • 原文地址:https://www.cnblogs.com/jeet/p/116003.html
Copyright © 2020-2023  润新知