gpt4 book ai didi

wcf - WCF 服务中的自定义客户端证书和用户名验证

转载 作者:行者123 更新时间:2023-12-04 11:14:24 25 4
gpt4 key购买 nike

我的特殊问题是这样的:

  • 我们目前正在运行一组服务,要求客户端在调用服务时提供用户名和密码作为身份验证。
  • 我们希望在这些服务上实现 PKI 基础设施,但我们的一些合作伙伴将使用比其他合作伙伴更长的时间来适应这种新的基础设施。
  • 作为第一步,我们希望从我们的一些合作伙伴那里获得客户证书。访问他们在我们服务器上的数据需要客户端证书(除了用户名和密码),而其他用户只需要用户名和密码。

  • 为了解决这个问题,我尝试在 WCF 中为用户名/密码身份验证(使用 UserNamePasswordValidator )和客户端证书(使用 X509CertificateValidator )实现自定义验证器。用户名/密码验证器将向我们的数据库验证这些凭据,而客户端证书验证器将检查请求是否来自我们需要证书的客户端,如果是,则验证是否提供了有效的客户端证书。我无法配置 WCF 以便它使用这两个验证器。
    我在服务器上的 WCF 配置当前设置如下:
    <behaviors>
    <serviceBehaviors>
    <behavior name="MyServiceBehavior">
    <serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
    <serviceDebug includeExceptionDetailInFaults="true" />
    <serviceCredentials>
    <clientCertificate>
    <authentication customCertificateValidatorType="MyWS.Security.MyServicesCertificateValidator, MyWS"
    certificateValidationMode="Custom" revocationMode="NoCheck" />
    </clientCertificate>
    <userNameAuthentication userNamePasswordValidationMode="Custom"
    customUserNamePasswordValidatorType="MyWS.Security.MyServicesUsernameValidator, MyWS" />
    </serviceCredentials>
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <bindings>
    <basicHttpBinding>
    <binding name="MySoapBinding">
    <security mode="TransportWithMessageCredential">
    <transport clientCredentialType="Certificate" />
    <message clientCredentialType="UserName" />
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <services>
    <service behaviorConfiguration="MyServiceBehavior" name="MyWS.Services.TheService">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="MySoapBinding" name="TheService" bindingNamespace="https://services.my/TheService" contract="MyWS.Interfaces.Service.ITheService" />
    <host>
    <baseAddresses>
    <add baseAddress="https://localhost:4434/MyWS/TheService"/>
    </baseAddresses>
    </host>
    </service>
    </services>
    据我了解,此配置无效,因为我无法使用 customCertificateValidatorType在传输层(因为 IIS 在此处涉及 WCF 之前检查证书),但我看不到如何将 customCertificateValidatorType 两者结合起来和 customUserNamePasswordValidatorType作为消息层的凭证类型。
    我已经实现了一个消息检查器,也许可以使用 OperationContext 来解决问题。以某种方式(如下面的链接中所建议的),但我还没有找到一种方法让我这样做。
    http://social.msdn.microsoft.com/Forums/en/wcf/thread/b6ab8b58-516b-41d4-bb0e-75b4baf92716
    我想我可能正在尝试实现与 WCF 工作方式不兼容的东西,但如果有人知道如何解决这个问题,我会很高兴收到您的反馈。

    最佳答案

    我想我现在已经找到了解决我的问题的方法,这要归功于@ladislav-mrnka 在他的回答中提供的宝贵意见。我意识到有必要提供两个端点来配置不同的需求,并且我还了解了配置服务时支持 token 的可能性。

    我找到了一个关于 supporting tokens 的链接在 MSDN 上,并按照这个配方,我已经使用以下自定义绑定(bind)在服务器上实现了端点(我通过代码切换到配置。不确定这是否也可以在 web.config 中设置。)

    private static Binding CreateMultiFactorAuthenticationBinding()
    {
    var httpsTransport = new HttpsTransportBindingElement();

    // The message security binding element will be configured to require 2 tokens:
    // 1) A username-password encrypted with the service token
    // 2) A client certificate used to sign the message

    // Create symmetric security binding element with encrypted username-password token.
    // Symmetric key is encrypted with server certificate.
    var messageSecurity = SecurityBindingElement.CreateUserNameForCertificateBindingElement();
    messageSecurity.AllowInsecureTransport = false;

    // Require client certificate as endorsing supporting token for all requests from client to server
    var clientX509SupportingTokenParameters = new X509SecurityTokenParameters
    {
    InclusionMode =
    SecurityTokenInclusionMode.AlwaysToRecipient
    };
    messageSecurity.EndpointSupportingTokenParameters.Endorsing.Add(clientX509SupportingTokenParameters);

    return new CustomBinding(messageSecurity, httpsTransport);
    }

    此绑定(bind)创建一个 SymmetricSecurityBindingElement其中对称 key (使用服务器证书加密)用于加密消息头中的用户名/密码安全 token 以及消息正文本身。

    此外,X509 安全 token 作为背书支持 token 添加到绑定(bind)。此 token 配置为始终包含在客户端对服务器的请求中。

    此自定义绑定(bind)随后用于配置具有需要此绑定(bind)的端点的新 WCF 服务。我正在使用 CaSTLe Windsor 中的 WcfFacility 来配置服务。

    此代码执行以下操作:
  • 设置服务证书
  • 将客户端证书的验证模式设置为链式信任,以便传入的客户端证书必须由服务器存储中的受信任根证书颁发机构颁发
  • 为用户名/密码凭据和客户端证书添加自定义验证器

  • //// Registering WCF-services
    var returnFaults = new ServiceDebugBehavior {IncludeExceptionDetailInFaults = true};
    var metaData = new ServiceMetadataBehavior {HttpsGetEnabled = true};

    var serviceCredentials = new ServiceCredentials();

    // Configure service sertificate
    serviceCredentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "ServerCertificate");

    // Configure client certificate authentication mode
    serviceCredentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;

    // Add custom username-password validator
    serviceCredentials.UserNameAuthentication.UserNamePasswordValidationMode =
    UserNamePasswordValidationMode.Custom;
    serviceCredentials.UserNameAuthentication.CustomUserNamePasswordValidator =
    _container.Resolve<MyServicesUsernameValidator>();

    // Add custom certificate validator
    serviceCredentials.ClientCertificate.Authentication.CertificateValidationMode =
    X509CertificateValidationMode.Custom;
    serviceCredentials.ClientCertificate.Authentication.CustomCertificateValidator =
    _container.Resolve<MyServicesCertificateValidator>();

    var serviceModel = new DefaultServiceModel();

    serviceModel.AddEndpoints(
    WcfEndpoint.ForContract<IMyContract>().BoundTo(CreateMultiFactorAuthenticationBinding()));
    serviceModel.BaseAddresses.Add(new Uri("https://server.com/MyServiceImplementation.svc"));

    serviceModel.AddExtensions(serviceCredentials);
    serviceModel.AddExtensions(metaData);

    _container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
    .Register(Component.For<IMyContract>()
    .ImplementedBy<MyServiceImplementation>()
    .AsWcfService(serviceModel),
    Component.For<IServiceBehavior>().Instance(returnFaults));

    MyServicesUsernameValidator 继承 UserNamePasswordValidator,MyServicesCertificateValidator 继承 X509CertificateValidator。两者都覆盖了它们对应的 Validate 方法。

    这似乎解决了我的特殊问题......希望它能解决你的问题! :)

    关于wcf - WCF 服务中的自定义客户端证书和用户名验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6583246/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com