none
用户登录与验证的问题,很苦恼 RRS feed

  • 问题

  • 我现在要用WCF做一个数据平台,但是这个平台不是谁都能访问的,需要通过用户名和密码验证身份

    然而,我这里既没有域环境,也没有可信的证书

    我采用的方法是:在每一个函数里都加上用户名和密码两个参数,比如这样:fun1(string username,string password,……)

    显然,这样每次客户端调用,都需要执行用户身份验证,这显然很重复,而且效率底下。

    我想知道的是,有没有一种方法,使得客户端第一次连接时,验证用户身份,验证完毕后,将用户信息保存下来,就像ASP.NET里的Session保存UserID一样,以此来判定该用户是否登录

    2011年1月18日 13:38

答案

  • #若需要限制IP,只能在ServiceOperation里实现了。

    是的。

    当然也可以写MessageInspector,用AOP的形式插入IP过滤功能,这样可能会整洁一些

    #在Service的函数里,如何获取到用户通过ClientCredentials.UserName.UserName传过来的用户名

    OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

     

    • 已编辑 Mog Liang 2011年1月20日 9:18 补充回答
    • 已标记为答案 a4712635 2011年1月23日 3:10
    2011年1月20日 8:51

全部回复

  • 那你也可以使用其它验证方式啊。 比如对客户端使用简单的Basic验证。 Proxy提供一次验证之后,服务端针对这个Proxy的调用都会共享一个验证结果。 调用方法里传用户名密码的问题是,即使验证失败,也必须实例化服务类。而且中间有消息的映射过程。 效率会低很多。
    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
     

    老徐的网站】:http://www.frankxulei.com/

    微软WCF中文技术论坛
    微软WCF英文技术论坛

    Windows Azure中文技术论坛

    2011年1月18日 15:18
    版主
  • 你是用的http协议么?如果是 加用户验证的module上去可不可以?
    2011年1月18日 20:53
  • 请问你说的这个客户端Basic验证怎么整?我现在没法用证书啊,我现在用的是basicHttpBinding

    还有一个问题在于,我还想在验证之后,从数据库读取用户的权限信息,然后保存在会话级,后面用户再调用其他方法时,需要判断用户是否拥有调用这个方法的权限

    请问这个如何实现?

    2011年1月19日 3:31
  • 怎么弄?

    我的宿主用的是Windows Service或者命令行应用程序,不是IIS

    2011年1月19日 6:12
  • 我整出来了,还是得用证书,不过我制作证书的时候,使用者的名字和服务器IP设置成一样,然后把证书导入到客户端,再在配置文件里配置<authentication certificateValidationMode="None"/>,客户端就完全信任服务端证书了

    现在用自定义身份验证可以实现身份验证,但是我还是那个问题,如果我还想在验证之后,从数据库读取用户的权限信息,然后保存在会话级,后面用户再调用其他方法时,需要判断用户是否拥有调用这个方法的权限

    这个怎么弄

    2011年1月19日 8:59
  • 我做了一次测试,同一个proxy,为什么每次调用远程方法的时候,都需要验证用户名和密码?这岂不是太频繁了

    我设置了PerSession,也是每次都验证

    2011年1月19日 11:47
  • 可以缓存起来,用户的权限和ID都缓存到服务端。
    你随时可以开始!
    2011年1月19日 14:45
    版主
  • 怎么缓存????
    2011年1月19日 15:00
  • 怎么弄?

    我的宿主用的是Windows Service或者命令行应用程序,不是IIS


    你是回我的帖子么?如果用的不是iis 估计不能用httpmodule...

    看看下面这个有用没用。。。

    http://msdn.microsoft.com/en-us/library/ms731774.aspx

    2011年1月19日 17:02
  • ASP.NET 中,用户的credential实际上是保存在服务端的,用户只是拥有一个key,随着cookie存在于整个会话过程中。 若你对ASP.net form authentication 和 Membership熟悉的话,你可以尝试启用 WCF的 AspNetCompatibility 模式, 并且配置binding,使其允许在HTTP上携带cookie。参见文章:

    http://msdn.microsoft.com/en-us/library/aa702682.aspx

    另外,WCF提供了非常丰富的authentication/authorization方法,至于你想使用自定义的用户名密码方式验证,我建议你选择 TransportWithMessageCredential模式,你需要一个证书用作HTTPS通道,然后配置username authentication方式,并利用membership的基础设施。

    关于如何配置TransportWithMessageCredential且使用Username凭证,参考

    http://mogliang.blogspot.com/2010/06/how-to-host-wcf-on-cloud-with-transport.html (可能要代理才能访问)

    关于如何配置Membership provider,参考

    http://msdn.microsoft.com/en-us/library/ms731049.aspx

     

    你先选择验证方式,并自己先实验一下,将遇到的问题帖出来,大家会协助你解决

    谢谢,


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    2011年1月20日 3:33
  • 十分感谢版主的帮助

    我觉得WCF这东西越做问题越多,而且百度都搜不到解决方法,只能来论坛求救

    我有个问题,启用AspNetCompatibility 是不是以为着宿主只能是IIS?

    我现在用的就是TransportWithMessageCredential模式

    这是我的配置文件:

      <bindings>
       <wsHttpBinding>
        <binding name="bindingConfiguration">
         <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="Basic"></transport>
          <message clientCredentialType="UserName"/>
         </security>
         <reliableSession enabled="true"/>
        </binding>
       </wsHttpBinding>
      </bindings>
    
         <serviceCredentials>
          <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="192.168.1.14" storeLocation="LocalMachine"/>
          <clientCertificate>
           <authentication certificateValidationMode="None"/>
          </clientCertificate>
          <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TeachInfoPlatform.UserPasswordValidator,TeachInfoPlatform"/>
         </serviceCredentials>
    

    虽然已经实现了自定义用户名和密码的功能,但是这不能满足我的需求

    我在自定义的身份验证方法中,不仅需要验证用户名和密码,还要验证对方IP地址,由于在身份验证时,服务还没有实例化,因此OperationContract.Context是空的,没法获取IP,请问版主还有没有其他方法获取IP?

    验证身份完毕后,我还希望从数据库中提取该用户的权限信息,以后用户调用函数时,可以根据用户的权限信息,判断能否调用该函数。不知道这个能不能实现

    2011年1月20日 7:29
  • # 启用AspNetCompatibility 是不是以为着宿主只能是IIS?

    AspNetCompatibility 要求WCF是和ASP.net application host在一起,也就是说不能使用WCF selfhost。

    # 我在自定义的身份验证方法中,不仅需要验证用户名和密码,还要验证对方IP地址,由于在身份验证时,服务还没有实例化,因此OperationContract.Context是空的,没法获取IP,请问版主还有没有其他方法获取IP?

    UserNamePasswordValidator 是运行在独立于Service实例的线程上,无法访问OperationContract.Context。你若需要限制IP,只能在ServiceOperation里实现了。

    # 我还希望从数据库中提取该用户的权限信息,以后用户调用函数时,可以根据用户的权限信息,判断能否调用该函数

    这实际上是Authorization功能,WCF实现了此功能,参考

    http://msdn.microsoft.com/en-us/library/ms733071.aspx

    http://msdn.microsoft.com/en-us/magazine/cc948343.aspx

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    2011年1月20日 8:37
  • # 启用AspNetCompatibility 是不是以为着宿主只能是IIS?

    AspNetCompatibility 要求WCF是和ASP.net application host在一起,也就是说不能使用WCF selfhost。

    # 我在自定义的身份验证方法中,不仅需要验证用户名和密码,还要验证对方IP地址,由于在身份验证时,服务还没有实例化,因此OperationContract.Context是空的,没法获取IP,请问版主还有没有其他方法获取IP?

    UserNamePasswordValidator 是运行在独立于Service实例的线程上,无法访问OperationContract.Context。你若需要限制IP,只能在ServiceOperation里实现了。

    # 我还希望从数据库中提取该用户的权限信息,以后用户调用函数时,可以根据用户的权限信息,判断能否调用该函数

    这实际上是Authorization功能,WCF实现了此功能,参考

    http://msdn.microsoft.com/en-us/library/ms733071.aspx

    http://msdn.microsoft.com/en-us/magazine/cc948343.aspx

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework


    若需要限制IP,只能在ServiceOperation里实现了。

    ServiceOperation指的就是具体的服务的代码实现过程?

    我还有一个问题,在Service的函数里,如何获取到用户通过ClientCredentials.UserName.UserName传过来的用户名

    2011年1月20日 8:49
  • #若需要限制IP,只能在ServiceOperation里实现了。

    是的。

    当然也可以写MessageInspector,用AOP的形式插入IP过滤功能,这样可能会整洁一些

    #在Service的函数里,如何获取到用户通过ClientCredentials.UserName.UserName传过来的用户名

    OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

     

    • 已编辑 Mog Liang 2011年1月20日 9:18 补充回答
    • 已标记为答案 a4712635 2011年1月23日 3:10
    2011年1月20日 8:51
  • #若需要限制IP,只能在ServiceOperation里实现了。

    是的。

    当然也可以写MessageInspector,用AOP的形式插入IP过滤功能,这样可能会整洁一些

    #在Service的函数里,如何获取到用户通过ClientCredentials.UserName.UserName传过来的用户名

    OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework

     

    谢谢版主了,我找到解决办法了,我用的是自定义授权管理器解决了我的问题 我现在调试的时候还有一点毛病,我是把服务端放在另一台计算机上,客户端在我的笔记本上 每次客户端调用远程方法的时候,都非常慢,有时候需要一分钟才能执行完毕,而服务端的方法都是些很简单的逻辑,比如输出一些什么信息 请问有什么解决方法吗?
    2011年1月20日 13:27
  • 我们最好先把问题范围缩小。

    • 你可以建立一个无安全设置的Endpoint,检查一下是否使用此Endpoint也有性能问题。
    • 检查是否网络连接速度很差。
    • 你也可以打开 WCF Trace,看webservice调用过程中是否发生了异常

    另外我记得WCF3.5有一个已知问题,当返回数组,并且设置了安全时,会有效率问题,你能否告诉我你的OperationContract和Web.config中<system.ServiceModel>节?你用的.net版本是多少?

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    2011年1月21日 1:49
  • 版主你好,我做了个试验,basicHttpBinding,无身份验证,服务端只有一个函数,打印helloworld

    客户端调用远程函数,依旧用了将近30秒

    我用的是4.0版本的WCF

    我的两台电脑用路由器连接,其中台式机做服务端,与路由器用双绞线连接

    笔记本做客户端,与路由器用WLAN连接

    就是这么个情况

    2011年1月21日 5:09
  • 你笔记本有没配置网络代理?

    你尝试设置 basichttpbinding 的 UseDefaultWebProxy 为false,看看是否解决问题

    你能否测试一下网络是否有问题?比如服务端host一个网页,用客户端访问,速度如何?


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    2011年1月21日 7:43
  • 笔记本没有设置网络代理

    UseDefaultWebProxy 设置成false了还是没用

    两台电脑之间通信应该没啥问题,我做了驱动器映射传文件都挺快

    2011年1月21日 11:31
  • 重新说明一下我的问题:

    客户端启动的时候,第一次执行到远程方法的时候,特别慢

    一旦这个方法执行完毕,后面再执行别的方法,就很快了

    我还有另外一个问题,我用的是wshttpbinding,这样客户端向服务端提交信息的时候,是不是信息的大小会受到服务端buffer的限制?

    2011年1月22日 4:53
  • #用的是wshttpbinding,这样客户端向服务端提交信息的时候,是不是信息的大小会受到服务端buffer的限制

    消息大小不受maxBufferSize限制,但是受maxReceivedMessageSize限制。

     


    Mog Liang
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    2011年1月24日 1:34