2012-03-13 36 views
14

Tôi đang viết dịch vụ WCF yêu cầu mạo danh và phiên.
ràng buộc netTCP Xà phòng An ninh Xà phòng Thất bại

Nó là ok khi tôi cố gắng gọi nó trên máy tính địa phương của tôi, nhưng trên máy từ xa nó luôn luôn thất bại với lỗi như vậy:

Security Support Provider Interface (SSPI) authentication failed. The server may not be running in an account with identity 'host/hostname'. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server.

Nếu tôi cung cấp một UPN, nó ném một bản sắc không ngoại lệ .

Dưới đây là cấu hình của tôi:

server Config (APP):

<system.serviceModel>  
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="default"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
      <serviceAuthorization impersonateCallerForAllOperations="true" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <bindings> 
     <netTcpBinding> 
     <binding name="DataService.netTcpBinding"> 
      <readerQuotas maxArrayLength="65535" maxBytesPerRead="2147483647" maxStringContentLength="2147483647"/> 
      <reliableSession enabled="true" inactivityTimeout="24:00:00" ordered="true"/>   
      <security mode="TransportWithMessageCredential"> 
      <message clientCredentialType="Windows" /> 
      <transport clientCredentialType="Windows"/>   
      </security> 
     </binding> 
     </netTcpBinding> 
    </bindings> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/> 
    <services> 
     <service behaviorConfiguration="default" name="DataService.DataService"> 
     <endpoint address="" binding="netTcpBinding" bindingConfiguration="DataService.netTcpBinding" 
      name="DataService.DataService" contract="DataService.IDataService"/> 
     <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://address:4504/"/> 
      <add baseAddress="net.tcp://address:4503/"/> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
</system.serviceModel> 

Khách hàng Config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel>  
     <bindings> 
      <netTcpBinding> 
       <binding name="DataService.DataService" closeTimeout="00:01:00" 
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
        transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" 
        hostNameComparisonMode="StrongWildcard" listenBacklog="10" 
        maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" 
        maxReceivedMessageSize="65536"> 
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
        <reliableSession ordered="true" inactivityTimeout="24.00:00:00" 
         enabled="true" /> 
        <security mode="TransportWithMessageCredential"> 
         <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
         <message clientCredentialType="Windows" algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </netTcpBinding> 
     </bindings> 
     <client> 
      <endpoint address="net.tcp://address:4503/" binding="netTcpBinding" 
       bindingConfiguration="DataService.DataService" 
       contract="ataService.IDataService" name="DataService.DataService"> 
       <identity> 
       <dns value="DOMAIN"/>             
       </identity> 
      </endpoint> 
     </client> 
    </system.serviceModel> 
</configuration> 

Bất kỳ trợ giúp sẽ được đánh giá rất nhiều.

Trả lời

19

Dịch vụ Windows tự đăng ký với Tên người dùng chính hoặc Tên chính của dịch vụ (documentation). Để báo giá từ liên kết đó: "Nếu dịch vụ đang chạy dưới tài khoản LocalSystem, LocalService hoặc NetworkService, tên dịch vụ chính (SPN) được tạo theo mặc định dưới dạng máy chủ lưu trữ/vì các tài khoản đó có quyền truy cập vào dữ liệu SPN của máy tính Nếu dịch vụ đang chạy dưới một tài khoản khác, Windows Communication Foundation (WCF) sẽ tạo một UPN theo dạng @. "Trên thực tế, báo giá này khá giống với thông báo lỗi của bạn. Vì vậy, có vẻ như ...

a) nếu dịch vụ đang chạy dưới tài khoản Dịch vụ cục bộ hoặc tài khoản chuẩn tương tự, thì bạn cần điều chỉnh tệp cấu hình của khách hàng để có điều này, nơi tên máy chủ thực tế là " địa chỉ" và thiết bị đầu cuối đang chạy trên cổng 4503:

<identity> 
    <servicePrincipalName value="host/address:4503" /> 
</identity> 

b) luân phiên, nếu bạn đang chạy dưới một tài khoản phục vụ tận tình (chúng ta hãy gọi nó là 'ServiceAccount' trên miền 'mydomain'), sau đó bạn muốn

<identity> 
    <userPrincipalName value="[email protected]" /> 
</identity> 

Xin lưu ý rằng bạn có thể cần sử dụng tên miền đủ điều kiện trong cả hai trường hợp, bao gồm cả cấp độ Rừng và Cây. Đối với một miền đơn giản bên trong mạng LAN/WAN riêng của bạn, điều đó sẽ có nghĩa là address.MyDomain.local và [email protected] Nếu tên miền của bạn nằm trong một cây được gọi là MyTree thì nó sẽ là [email protected]; nếu đó là trong một khu rừng được gọi là MyForest thì nó sẽ là [email protected] (và tương tự cho ServicePrincipalName). Tên đầy đủ điều kiện là cần thiết when you are using Kerberos để xác thực.

+1

Điều này là chính xác. Tôi cũng sẽ thêm rằng khi tiêu thụ các dịch vụ web được lưu trữ bởi IIS, danh tính phải khớp với bản sắc của hồ bơi ứng dụng mà dịch vụ đó đang sống. Điều này đã được thay đổi trong một số phiên bản của IIS (có thể là 7?) Từ NetworkService (nơi bạn sẽ sử dụng nguyên tắc người dùng 'NetworkService @ MACHINE-NAME') cho AppPoolIdentity (nơi bạn sẽ sử dụng nguyên tắc dịch vụ của' host/MACHINE-NAME'). – qJake

6

Ngoài ra còn có một bẩn hack, như được đăng here, here, và here, và phân tích here.

Bạn có thể cung cấp Tên dịch vụ giả chính (SPN). Trong trường hợp đó, WCF sẽ không thất bại, nhưng quay trở lại NTLM để xác thực không xác minh hiệu trưởng.

Vì vậy, cấu hình:

<identity> 
     <servicePrincipalName value="dummy" > 
    </identity> 

và lập trình

EndpointIdentity identity = EndpointIdentity.CreateSpnIdentity("dummy"); 

sử dụng ChannelFactory:

Uri uri = new Uri("net.tcp://<myServer>:<myPort>/myServiceAddress"); 
    ChannelFactory channelFactory = new ChannelFactory<IMyContract>(new NetTcpBinding()); 
    channelFactory.CreateChannel(new EndpointAddress(uri, identity) 

cũng sẽ làm việc.

Các vấn đề liên quan