为WCF问题定制ServiceAuthorizationManager

时间:2014-11-05 12:20:01

标签: c# wcf asp.net-mvc-4

我创建了自定义ServiceAuthorizationManager作为" CustomUserNamePasswordValidator"为我的WCF项目。下面是我项目的片段。我希望我的wcf在它实际开始调用WCF API之前调用这个授权类,但这不会发生。我的"登录" WCF API正在调用此授权类的paraller。因此,当客户端调用Login时,它会同时调用它们 " CustomUserNamePasswordValidator"和登录方法同时进行。

授权类

 public class CustomUserNamePasswordValidator : ServiceAuthorizationManager
 {
    HttpRequestMessageProperty httpProperties;
    string operationName;

    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        operationName = GetOperationName(operationContext);
        httpProperties = (HttpRequestMessageProperty)operationContext.IncomingMessageProperties["httpRequest"];
        string authHeader = httpProperties.Headers[HttpRequestHeader.Authorization];

        string subno = string.Empty;
        string password = string.Empty;
        string version = string.Empty;
        string credntialType = string.Empty;

            string[] credentials = authHeader.Split(':');
            credntialType = credentials[0];

               password = credentials[1];

                if (!AuthorizeUser(password))
                {
                    throw new ArgumentException("401:Token invalid or expired.(0x000)");                        
                }
            }
       }

     private int AuthenticateUser(string subno, string pin, string version)
      {
      }
  }

WCF客户端服务代码段

public class ClientService : IClientService
{
    public wsLoginResult LoginUser()
    {
            HttpRequestMessageProperty httpReqProps = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties["httpRequest"];
            string res = httpReqProps.Headers[HttpRequestHeader.Authorization];

            foreach (var item in res.Split(':'))                
                ActivityLog("Activity", "Login Steps", item, item); 
    }
}

Web.Config Snippet

 <?xml version="1.0"?>
<configuration>
<connectionStrings>
 <add name="wmas_subsConnectionString" connectionString="Data Source=WT;Initial Catalog=wmas;User ID=sa;Password=ra3?" providerName="System.Data.SqlClient"/>
 </connectionStrings>
 <system.web>
  <compilation targetFramework="4.5" debug="true"/>
  <httpRuntime targetFramework="4.5"/>
 </system.web>
 <system.serviceModel>
  <client>
  <endpoint  address="http://192.168.1.12:7002/MobileApplicationWS/MobileApplicationApiWSImplService"
            binding="basicHttpBinding" bindingConfiguration="MobileApplicationApiWSPortBinding"
            contract="VASService.MobileApplicationApiWS"
            name="MobileApplicationApiWSPort" />

 </client>
 <services>
  <service name="ClientService.ClientService" behaviorConfiguration="ClientService.ServiceBehavior">
    <endpoint address=""
              binding="webHttpBinding" bindingConfiguration="webHttpBindingConfiguration"
              contract="ClientService.IClientService" behaviorConfiguration="webBehaviour"/>
    <endpoint address="stream"
              binding="webHttpBinding" bindingConfiguration="webHttpBindingConfigurationStreamed"
              contract="ClientService.IClientService" behaviorConfiguration="webBehaviour"/>
    <endpoint address="mex"
              binding="mexHttpsBinding"
              contract="IMetadataExchange" />        
   </service>
 </services>
 <bindings>
  <basicHttpBinding>
    <binding name="MobileApplicationApiWSPortBinding" />
  </basicHttpBinding>
  <webHttpBinding>
    <binding name="webHttpBindingConfiguration" />
    <binding name="webHttpBindingConfigurationStreamed" transferMode="StreamedResponse" />
  </webHttpBinding>
  </bindings>
  <behaviors>
  <serviceBehaviors>
    <behavior name="ClientService.ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceAuthorization serviceAuthorizationManagerType="ClientService.CustomUserNamePasswordValidator, ClientService" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="webBehaviour">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
 </behaviors>
 <protocolMapping>
  <add binding="basicHttpsBinding" scheme="https"/>
  </protocolMapping>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
 <system.webServer>
 <modules runAllManagedModulesForAllRequests="true"/>
 <directoryBrowse enabled="true"/>
 </system.webServer>
  </configuration>

1 个答案:

答案 0 :(得分:0)

您的解决方案无法正常工作的原因是CustomUserNamePasswordValidator无法在RESTful服务中使用。看看:http://msdn.microsoft.com/en-us/library/aa354513(v=vs.110).aspx

该示例使用SOAP并定义激活serviceAuthorization标记的端点的行为。如果您没有定义端点的安全性,serviceAuthorization根本无法工作。

<bindings>
  <wsHttpBinding>
    <!-- username binding -->
    <binding name="Binding">
      <security mode="Message">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

在RESTful服务中没有SecurityMode = Message,只有3:None / Transport / TransportCredentialOnly。请在此处继续阅读:http://msdn.microsoft.com/en-us/library/bb924478(v=vs.110).aspx

clientCredentialType="UserName"仅在消息中可用。

您可以尝试将端点安全模式定义为:传输,然后将凭据类型定义为:基本/证书/摘要/无/ Ntlm / Windows,但是看作您的解决方案,这些都不能确定它的效果如何。

如果您要提取标题而不使用任何&#34;已批准的&#34;有(我认为)更好的身份验证方式。办法。尝试实施扩展服务:http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iparameterinspector(v=vs.110).aspx

祝你好运!