使用自定义 UserNamePasswordValidator 使用 WCF 服务

Consuming a WCF Service with custom UserNamePasswordValidator

我在 IIS 上的 windows 2019 服务器上有一个 WCF 服务 运行。该服务将由在 xamarin 环境中使用的 .Net Core 库使用。一切正常,直到我想添加我的自定义 UserNamePasswordValidator 以便为服务增加一些安全性。

我的 Web.config 服务器服务部分如下所示

<system.serviceModel>
    <services>
        <service name="aircu_web.UpdateService" behaviorConfiguration="debug">
            <endpoint address="" name="wsHttpEndpoint" binding="wsHttpBinding" bindingConfiguration="ServiceBinding" contract="aircu_web.IUpdateService" />
        </service>
    </services>
    <bindings>
        <wsHttpBinding>
            <binding name="ServiceBinding">
                <security mode ="Message">
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="production">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="debug">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials>
                    <serviceCertificate storeLocation="LocalMachine" x509FindType="FindByThumbprint" findValue="84 d2 c6 d8 85 17 48 30 04 9e 12 e0 bd f4 f3 36 c1 57 b5 6e" storeName="My"/>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="aircu_web.ApiKeyValidator,aircu_web"/>
                </serviceCredentials>
                
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

导航到 https://(mydomain)/UpdateService.svc 时,我可以看到“您已创建服务”站点。

当我向我的程序集添加服务引用时,向导工作正常并且我生成了所有代码,除了绑定和端点地址 - 这对我来说是新的。在更改服务之前,我的服务客户端的构造函数不需要额外的参数。

当我使用以下代码创建客户端并调用 api

var binding = new BasicHttpsBinding();
var ep = new EndpointAddress(@"https://(my domain)/UpdateService.svc");
var svc = new AirCU.Service.UpdateServiceClient(binding, ep);

我得到异常 在 https://(my domain)/UpdateService.svc 上没有监听可以接受消息的端点。这通常是由不正确的地址或 SOAP 操作引起的。有关详细信息,请参阅 InnerException(如果存在)。"

我想我的配置中某处存在问题,无论是客户端还是服务器...

我需要更改什么才能让一切恢复正常? :)

非常感谢

好吧,我自己想出来了。

Xamarin 和 .Net Standard 不支持 wsHttpEndpoints。我不得不切换到 basicHttpsBinding,Xamarin 不支持安全模式 TransportWithMessageCredential,所以我不得不坚持使用 Transport only。

最后我的 Web.config 部分是这样的:

<system.serviceModel>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <services>
        <service name="aircu_web.UpdateService" behaviorConfiguration="debug">
            <endpoint address="" name="HttpsEndpoint" binding="basicHttpsBinding" bindingConfiguration="ServiceBinding" contract="aircu_web.IUpdateService" />
        </service>
    </services>
    <bindings>
        <basicHttpsBinding>
            <binding name="ServiceBinding" maxReceivedMessageSize="1000000">
                <security mode ="Transport">
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </basicHttpsBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="production">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="debug">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials>
                    <serviceCertificate storeLocation="LocalMachine" x509FindType="FindByThumbprint" findValue="84 d2 c6 d8 85 17 48 30 04 9e 12 e0 bd f4 f3 36 c1 57 b5 6e" storeName="My"/>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="aircu_web.ApiKeyValidator,aircu_web"/>
                </serviceCredentials>
                
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

我还必须相应地更改我的客户端代码。

private UpdateService.UpdateServiceClient GetProxy()
    {
        var binding = new BasicHttpsBinding();
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        binding.Security.Mode = BasicHttpsSecurityMode.Transport;
        var ep = new EndpointAddress(@"https://(mydomain)/UpdateService.svc");
        var svc = new UpdateService.UpdateServiceClient(binding, ep);
        svc.ClientCredentials.UserName.UserName = "App";
        svc.ClientCredentials.UserName.Password = "****";
        return svc;
    }

我还必须将我的服务引用从我的库项目移动到我的 xamarin 项目,因为我无法弄清楚 System.ServiceModel 库的一些程序集不匹配。

我尝试将相同的 nuget 包安装到所有项目,删除它们,清除 bin 和 obj 文件夹,re-creating 项目 - 没有任何效果。所以我将整个服务引用移到了 xamarin 项目,现在它工作正常。也许有人可以告诉我那里出了什么问题。错误是“类型(某些数字)未知....”