2017-12-22 234 views
5

Tôi có dịch vụ WCF phát hành mã thông báo đang sử dụng Microsoft.IdentityModel (WIF 3.5) mà tôi cần nâng cấp lên System.IdentityModel (.NET 4.5) . Vấn đề là tôi không thể thay đổi tên gốc của dịch vụ, Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract, thành đối tác mới hơn, System.ServiceModel.Security.WSTrustServiceContract. Đối với một số lý do nó không được công nhận bởi IntelliSense:Không thể giải quyết/sử dụng System.ServiceModel.Security.WSTrustServiceContract làm tên dịch vụ

enter image description here

Các màu xanh nguệch ngoạc dòng lỗi là:

The 'name' attribute is invalid - The value 'System.ServiceModel.Security.WSTrustServiceContract' is invalid according to its datatype 'serviceNameType' 

tôi có tài liệu tham khảo lắp ráp để System.ServiceModelSystem.IdentityModel trong <assemblies> nút.

Ngay cả khi tôi bỏ qua những lỗi IntelliSense và chạy các dịch vụ và truy cập nó sử dụng trình duyệt Tôi nhận được lỗi metadata này:

Metadata publishing for this service is currently disabled. 

Metadata xuất bản kích hoạt vì vậy tôi nghĩ rằng đó là vì vấn đề tên của dịch vụ.

Ngoài ra tôi nhận được lỗi này từ VS.NET khách hàng kiểm tra WCF:

Error: Cannot obtain Metadata from http://localhost:49178/Services/Issuer.svc 
If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455. 
WS-Metadata Exchange Error  
URI: http://localhost:49178/Services/Issuer.svc  
Metadata contains a reference that cannot be resolved: 'http://localhost:49178/Services/Issuer.svc'.  
There was no endpoint listening at http://localhost:49178/Services/Issuer.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.  
The remote server returned an error: (404) Not Found. 
HTTP GET Error  
URI: http://localhost:49178/Services/Issuer.svc  
The HTML document does not contain Web service discovery information. 

Tôi nghĩ rằng "Metadata contains a reference that cannot be resolved" dòng cũng đề cập đến tên dịch vụ quyết lỗi.

Mọi ý tưởng về những việc cần làm ở đây? Tôi đánh giá cao bất kỳ sự giúp đỡ ..

Issuer.svc:

<%@ ServiceHost Language="C#" Debug="true" Factory="Identity.Services.Wcf.Core.CustomSecurityTokenServiceContractFactory" Service="CustomSecurityTokenServiceConfiguration" %> 

Factory:

public class CustomSecurityTokenServiceContractFactory : WSTrustServiceHostFactory 
.. 

dịch vụ:

public class CustomSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration 
.. 
+0

Bạn đã làm theo hướng dẫn tại [link] (https://docs.microsoft.com/en-us/dotnet/framework/security/guidelines-for-migrating-an-application-built-using-wif-3 -5-to-wif-4-5) –

+0

@SamuelShyu: vâng tôi đã làm. Tài liệu chỉ đề cập đến những thay đổi không gian tên, không có gì giống như thay đổi hành vi. Tôi thậm chí còn giải mã cả Microsoft.Identity. * Và System.Identity. * Các lớp và chúng giống hệt nhau. – dstr

+0

Hãy thử với gợi ý ở điểm 4 của câu trả lời của tôi: Nhấp vào "Nâng cao" và bỏ chọn "Sử dụng lại các loại trong hội đồng được tham chiếu" khi bạn tạo proxy. – Isma

Trả lời

3

Som etimes cách tốt nhất để giải quyết loại vấn đề này là tạo dự án WCF mới từ đầu, cấu hình lại điểm cuối của bạn vv .. và sao chép qua các dịch vụ hiện có từ dự án cũ của bạn, điều này đặc biệt đúng khi di chuyển từ phiên bản cũ hơn của WCF .

Dưới đây là một danh sách kiểm tra mà tôi làm theo mỗi khi tôi có vấn đề với các dịch vụ WCF:

Server

Hãy chắc chắn rằng các hợp đồng dịch vụ của bạn được định nghĩa sử dụng giao diện với các thuộc tính thích hợp, ví dụ:

IMyService.cs

[ServiceContract] 
public interface IMyService 
{ 
    [OperationContract] 
    int ThisAnOperation(int a, int b); 
} 

Kiểm tra xem bạn đã triển khai hợp đồng của mình bằng giao diện đúng chưa:

MyService.cs

public class MyService: IMyService 
{ 
    public int ThisAnOperation(int a, int b) 
    { 
     return a * b; 
    } 
} 

Bạn cần phải có một máy chủ dịch vụ để truy cập dịch vụ của bạn, họ là những file có phần mở rộng .svc:

  • Tạo một file myService.svc.
  • Thêm dòng mã sau đây, tham khảo các lớp thực hiện dịch vụ của bạn:

    <%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.MyService" CodeBehind="MyService.cs" %>

Cuối cùng, bạn cần phải thiết lập một ràng buộc mà sẽ xác định mà vận chuyển và các giao thức có sẵn để truy cập máy chủ của bạn, bắt đầu với một ràng buộc HTTP cơ bản đơn giản để kiểm tra xem dịch vụ của bạn có đang hoạt động như mong đợi hay không, sau đó thay đổi nó thành sản phẩm sẵn sàng hơn bao gồm xác thực và/hoặc mã hóa và nén khi cần.

Để thiết lập cơ bản ràng buộc HTTP:

  1. Tháo khối <system.serviceModel>...</system.serviceModel> từ file web.config của bạn nếu nó đã ở đó.

  2. Xây dựng giải pháp của bạn, nó sẽ biên dịch thành công, nếu không sửa bất kỳ lỗi nào và thử lại.

  3. Nhấp chuột phải vào tệp web.config của bạn rồi nhấp vào "Chỉnh sửa cấu hình WCF", sau đó nhấp vào "Tạo dịch vụ mới" và trong Loại dịch vụ, duyệt và chọn tệp DLL được tạo khi bạn biên soạn dịch vụ của mình (phải ở trong thư mục bin) và chọn lớp dịch vụ mà bạn muốn xuất bản:

Service Selection

  1. Xác định hợp đồng sử dụng dịch vụ (nên được tự động lấp đầy).

  2. Trong trang tiếp theo, chọn giao thức truyền tải cho dịch vụ của bạn, trong trường hợp này là "HTTP", sau đó chọn "Khả năng tương tác của dịch vụ web cơ bản".

  3. Trong trang tiếp theo bạn có thể chỉ định địa chỉ cho điểm cuối, cho mục đích thử nghiệm, bạn có thể để trống trường này (đảm bảo bạn cũng xóa "HTTP" khỏi trường văn bản).

  4. Nhấp vào tiếp theo, đóng cửa sổ cấu hình và lưu.

Bây giờ bạn sẽ có thể chạy dịch vụ và duyệt đến MyService.svc để truy cập dịch vụ của bạn.

  1. Kích hoạt xuất bản siêu dữ liệu để dịch vụ của bạn có thể được tìm thấy, để thực hiện việc này, thêm hành vi sau đây vào web của bạn.cấu hình:

    <system.serviceModel> 
        <services> 
         <service name="WcfService1.MyService"> 
          <endpoint binding="basicHttpBinding" 
            bindingConfiguration="" contract="WcfService1.IMyService" 
           BehaviorConfiguration="MyServiceBehaviors" /> 
         </service> 
        </services> 
    </system.serviceModel> 
    
    <behaviors> 
        <serviceBehaviors> 
         <behavior name="MyServiceBehaviors" > 
          <serviceMetadata httpGetEnabled="true" /> 
         </behavior> 
        </serviceBehaviors> 
    </behaviors> 
    

Bây giờ bạn sẽ có thể để chạy dự án của bạn và nhận được một trang mô tả siêu dữ liệu của dịch vụ của bạn trong trình duyệt, thông tin này có thể được sử dụng bởi khách hàng để tìm ra dịch vụ và tạo ra một proxy của các dịch vụ:

The Client

  1. Xóa bất kỳ tài liệu tham khảo phục vụ hiện tại từ dự án của bạn.
  2. Nhấp chuột phải vào tên dự án của bạn sau đó trong "Add Service Reference", nhập vào địa chỉ dịch vụ của bạn và bấm vào "Go", nếu tất cả mọi thứ đã đi tất cả các bên phải, bạn sẽ thấy dịch vụ của bạn trong cửa sổ dịch vụ:

Service Reference

  1. Cố gắng tạo proxy bằng cách hoàn thành thuật sĩ, xây dựng lại dự án của bạn và dùng thử. Nếu bạn vẫn còn có cùng một vấn đề, xóa các tham chiếu được tạo và lặp lại điểm 1 và 2 và sau đó:

  2. Bấm vào nút "Advanced" và bỏ chọn "loại tái sử dụng trong hội đồng tham chiếu":

Advanced service settings

Sau đó hoàn thành trình hướng dẫn và biên dịch.

Hy vọng rằng, mọi thứ sẽ hoạt động ngay bây giờ !!!

+1

Tôi đánh giá cao nỗ lực nhưng điều này không thực sự áp dụng cho trường hợp của tôi vì không có ServiceContract trong dịch vụ này. SVC sử dụng một lớp với WSTrustServiceHostFactory làm lớp cơ sở làm nhà máy và điều này sử dụng Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract làm tên dịch vụ và IWSTrust13SyncContract (và các biến thể khác) làm hợp đồng. Đó là lỗi của tôi tôi nên rõ ràng hơn về dịch vụ. Cảm ơn bạn mặc dù. – dstr

+0

Không vấn đề gì, bạn đã thử cài đặt "Tái sử dụng các loại trong hội đồng tham chiếu" chưa? Tôi đã giải quyết một lỗi tương tự với cài đặt đó. – Isma

1

Tôi có thể có thiết lập tương tự như của bạn. Trong trường hợp của tôi, tôi có cả STS và một dịch vụ được gọi bởi bất kỳ ai muốn có một mã thông báo. Đây là những gì bạn có, phải không?

Trong Web.config cho STS thực tế tôi có:

<bindings> 
    <ws2007HttpBinding> 
    <binding name="ws2007HttpBindingConfiguration"> 
     <security mode="TransportWithMessageCredential"> 
     <message establishSecurityContext="false" clientCredentialType="Certificate"/> 
     </security> 
    </binding> 
    </ws2007HttpBinding> 
</bindings> 
<services> 
    <service name="System.ServiceModel.Security.WSTrustServiceContract" behaviorConfiguration="STSBehavior"> 
    <endpoint address="IWSTrust13" binding="ws2007HttpBinding" bindingConfiguration="ws2007HttpBindingConfiguration" contract="System.ServiceModel.Security.IWSTrust13SyncContract" name="STSWCF"/> 
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> 
    </service> 
</services> 

Và trong Web.config cho dịch vụ tôi có:

<protocolMapping> 
    <!-- We want to use ws2007FederationHttpBinding over HTTPS --> 
    <add scheme="https" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration"/> 
</protocolMapping> 
<bindings> 
    <ws2007FederationHttpBinding> 
    <binding name="ws2007FederationHttpBindingConfiguration"> 
     <!-- We expect a bearer token sent through an HTTPS channel --> 
     <security mode="TransportWithMessageCredential"> 
     <message establishSecurityContext="false"> 
      <issuerMetadata address="https://localhost/Identity.STS.WCF/Service.svc/mex"/> 
     </message> 
     </security> 
    </binding> 
    </ws2007FederationHttpBinding> 
</bindings> 
<services> 
    <service name="Identity.Auth.WCF.Service" behaviorConfiguration="STSBehavior"> 
    <endpoint address="https://localhost/Identity.Auth.WCF/Service.svc" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration" contract="Identity.Auth.WCF.IService" name="Identity.Auth.WCF"/> 
    </service> 
</services> 

Ngoài ra, nó không làm việc cho tôi ở đây , mặc dù tôi nhận được lỗi IntelliSense giống như bạn, và trong cùng một vị trí.

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