2013-11-27 77 views
9

我想用wcf做一個非常基本但安全的用戶名/密碼身份驗證。WCF的基本身份驗證

但是,當我查看ServiceSecurityContext.Current.PrimaryIdentity;的值時,它包含我的Windows機器的憑據並聲明它已被授權(即使我尚未執行任何授權),而不是提供給服務的用戶名和密碼。

我服務的web.config文件是如下

<?xml version="1.0"?> 
<configuration> 

    <appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5"/> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <!-- To avoid disclosing metadata information, set the values below to false before deployment --> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="WsHttpBindingConfig"> 
      <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None" /> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 

    </bindings> 
    <protocolMapping> 
     <add binding="wsHttpBinding" scheme="http" /> 
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <!-- 
     To browse web app root directory during debugging, set the value below to true. 
     Set to false before deployment to avoid disclosing web app folder information. 
     --> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 

</configuration> 

和客戶端應用程序的的app.config如下

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
    <system.serviceModel> 
     <bindings> 
      <wsHttpBinding> 
       <binding name="WSHttpBinding_IService1" /> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://localhost/WcfSecuredService/Service1.svc" 
       binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" 
       contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
</configuration> 

我所說的服務,下面的代碼

ServiceReference1.Service1Client clnt = new ServiceReference1.Service1Client(); 
      clnt.ClientCredentials.UserName.UserName = "peter"; 
      clnt.ClientCredentials.UserName.Password = "grr"; 

      string result=clnt.GetSecuredData(); 

我在做什麼錯?

請注意,客戶端應用程序和服務都在同一臺計算機上運行。我不知道如果身份是運行該服務的機器或從客戶端傳遞給它的機器,因爲它們都是相同的憑據.....

我想其他問題可能是「如何做我得到了傳遞給服務的用戶名和密碼?「

回答

5

我現在已經制定了這一點

我需要創建一個自定義的驗證類,我發現這裏How to: Use a Custom User Name and Password Validator

我還需要向Web進行一些更改。配置

<?xml version="1.0"?> 
<configuration> 

    <appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5"/> 
    </system.web> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfService1Secure.Auth,WcfService1Secure" /> 
      </serviceCredentials> 
      <!-- To avoid disclosing metadata information, set the values below to false before deployment --> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="WsHttpBindingConfig"> 
      <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None" /> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 

    </bindings> 
    <protocolMapping> 
     <add binding="wsHttpBinding" scheme="https" bindingConfiguration="WsHttpBindingConfig" /> 
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <!-- 
     To browse web app root directory during debugging, set the value below to true. 
     Set to false before deployment to avoid disclosing web app folder information. 
     --> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 

</configuration> 

和在app.config

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 

    <system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="BasicHttpBinding_IService1" /> 
      </basicHttpBinding> 
      <wsHttpBinding> 
       <binding name="WSHttpBinding_IService1"> 
        <security mode="TransportWithMessageCredential"> 
         <transport clientCredentialType="None" /> 
         <message clientCredentialType="UserName" /> 
        </security> 
       </binding> 
      </wsHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="https://localhost/WcfService1Secure/Service1.svc" 
       binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" 
       contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" /> 
     </client> 
    </system.serviceModel> 
</configuration> 

現在,用戶是在所述請求驗證和用戶名是可用的使用

ServiceSecurityContext.Current.PrimaryIdentity;

+0

我嘗試了幾次,但訪問'ServiceSecurityContext.Current.PrimaryIdentity'時得到的用戶名似乎並不是用來進行身份驗證的用戶。你能在這裏談一談嗎? –

2

嗨,你應該補充一點,可以在你的服務器端接受登錄名和密碼,並將它們存儲在一個變量或數據庫的方法
你的方法應該是這樣的

​​

clnt.SignUp(login,password); 

你在做什麼可以在一個獨立的應用程序,但不是在網絡電話 您的方法服務調用將有類似於

http://MyService/IMyContract/MyAction1

希望這有助於

+0

我真的不想在每次調用時都手動傳遞證書。當然,他們應該由Service1Client自動傳遞? – coolblue2000

+0

你在做什麼我懷疑這將自動通過你是在SOAP環境意味着一切都是disconected –

+0

我認爲憑據由代理傳遞到肥皂頭?否則爲什麼有一個憑據屬性呢?我見過很多這種工作的例子,只是他們似乎都使用sqlmembership提供程序以及其他我不想使用的東西。我只想使用肥皂標題自動傳遞的用戶名和密碼進行身份驗證。 – coolblue2000

1

如果您正在使用PerSession實例,那麼你可以先打電話驗證服務器和成功的維持在服務器上的標誌,隨後調用將檢查標誌執行前。這意味着客戶端需要首先調用Authenticate方法,然後只調用其他方法。

如果不使用PerSession實例,您可以爲服務器創建自己的代理類,並且在創建代理實例時接受它可以在每個調用中傳遞的LoginName/Password,並在服務器端實現自定義的ServiceAuthorizationManager,它可以從OperationContext .Current.IncomingMessageHeaders並驗證它。

+0

關於non-persession實例,這不是scf應該默認做什麼(因此憑證屬性)? – coolblue2000