【问题标题】:Inject an object into a custom WCF UserNamePassValidator - Autofac将对象注入自定义 WCF UserNamePassValidator - Autofac
【发布时间】:2012-09-16 03:09:37
【问题描述】:

我有一个托管在 IIS 中的服务。由 Web.config 配置。

我创建了一个自定义 UserNamePassValidator,如果我在 validate 方法中有逻辑,它就可以工作。但我想要另一个项目中的逻辑并使用 DI 注入如下。

public class UserNamePassValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
{
    private readonly ISystemAuthentication _systemAuthentication;

    public UserNamePassValidator(ISystemAuthentication systemAuthentication)
    {
        _systemAuthentication = systemAuthentication;
    }

    public override void Validate(string userName, string password)
    {
        _systemAuthentication.Validate(userName, password))
    }
}

我正在使用 Autofac WCF 集成。

var builder = new ContainerBuilder();
builder.RegisterType<AuthenticationService>().As<IAuthenticationService>();
builder.Register(c => new SystemAuthentication()).As<ISystemAuthentication>();
builder.Register(c => new UserNamePassValidator(c.Resolve<ISystemAuthentication>()));
AutofacHostFactory.Container = builder.Build();

当我浏览到该服务时,我收到以下错误:

[MissingMethodException: No parameterless constructor defined for this object.]

web.config 行为;

 <userNameAuthentication
                 userNamePasswordValidationMode="Custom"
                 customUserNamePasswordValidatorType="MyNamespace.UserNamePassValidator, service" />

我已阅读以下相关帖子,但示例是自托管服务: How to inject an object into a WCF validator class

编辑

  <system.serviceModel>
    <services>
      <service behaviorConfiguration="Namespace.AuthenticationServiceBehaviour" name="Namespace.AuthenticationService" >
        <endpoint address="" binding="wsHttpBinding" contract="Namespace.IAuthenticationService" bindingConfiguration="SafeServiceConf">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Namespace.AuthenticationServiceBehaviour">
          <serviceMetadata httpGetEnabled="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" />
          <serviceCredentials>
            <serviceCertificate findValue="AuthenticationService" 
              storeLocation="LocalMachine"
              storeName="My" 
              x509FindType="FindBySubjectName" />
            <userNameAuthentication
              userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="Namespace.UserNamePassValidator, Service" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="SafeServiceConf" maxReceivedMessageSize="65536">
          <readerQuotas maxStringContentLength="65536" maxArrayLength="65536" maxBytesPerRead="65536" />
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

系统认证类

public class SystemAuthentication : ISystemAuthentication
{
   public bool Validate(string userName, string password)
   {
       // removed code for abbreviation
       return true;
   }

WCF 身份验证服务

public class AuthenticationService : IAuthenticationService
    { 
        public bool Authenticate(string email, string password)
        {
            // removed for abbreviation
            return true;
        }
    }

【问题讨论】:

    标签: wcf dependency-injection wcf-security autofac


    【解决方案1】:

    来自这篇帖子UserNamePasswordValidator: When DI and Framework collide的帮助

    从我删除的 XML 配置中:

    <userNameAuthentication
       userNamePasswordValidationMode="Custom"
       customUserNamePasswordValidatorType="MyNamespace.UserNamePassValidator, service" />
    

    我将行为添加到 AutoFacHostFactory 服务主机

       IContainer container = builder.Build();
        AutofacHostFactory.Container = container;
        AutofacHostFactory.HostConfigurationAction = host =>
        {
            var auth = host.Credentials.UserNameAuthentication;
            auth.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
            auth.CustomUserNamePasswordValidator = container.Resolve<UserNamePassValidator>();
        };
    

    这非常有效,但如果能够从 web.config 中完成它会更好。如果有人知道更好的方法,请发布:)

    【讨论】:

    • > “我将行为添加到 AutoFacHostFactory 服务主机”。我需要在 WCF 项目中的哪里添加此代码?
    • @sp7 添加到service markup:&lt;%@ ServiceHost Service="TestService.Service1, TestService" Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" %&gt;
    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多