我有一个使用NetHttpsBinding的自托管WCF双工服务。它设置为通过UserNamePasswordValidator使用自定义用户名/密码身份验证进行客户端身份验证,并使用证书进行服务授权。 Connection工作正常,但从不调用UserNamePasswordValidator,因此我可以使用任何用户名和密码组合进行连接。所以我的问题是为什么它忽略了我的UserNameValidator?
以下是该服务的完整配置文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<system.serviceModel>
<services>
<service name="SchoolTestMaker.Service.SchoolTestMakerService">
<endpoint address="" binding="netHttpsBinding" bindingConfiguration="netHttpsEndpointBinding" contract="SchoolTestMaker.Service.ISchoolTestMakerService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True" />
<!--<serviceAuthorization principalPermissionMode="Custom" />-->
<serviceCredentials>
<serviceCertificate findValue="**classified(FBI)**"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netHttpsBinding>
<binding name="netHttpsEndpointBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netHttpsBinding>
</bindings>
</system.serviceModel>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
UserNamePasswordValidator:
public class SchoolTestMakerServiceUserNamePasswordValidator:UserNamePasswordValidator
{
IUnitOfWork unitOfWork;
IHashGenerator hashGenerator;
public SchoolTestMakerServiceUserNamePasswordValidator(IUnitOfWork unitOfWork,IHashGenerator hashGenerator)
{
this.unitOfWork = unitOfWork;
this.hashGenerator = hashGenerator;
}
public override void Validate(string userName, string password)
{
throw new Exception();
/*if(userName==null||password==null)
{
throw new ArgumentNullException();
}
string passwordHash = hashGenerator.GenerateHash(password);
UserAccount userAccount = unitOfWork.Repository<UserAccount>().Get(x => x.UserName == userName && x.PasswordHash == passwordHash);
if(userAccount==null)
{
throw new SecurityTokenException("Unknown Username or Incorrect Password");
}*/
}
}
StartService方法:
public void StartService()
{
serviceHost = new UnityServiceHost(container,
typeof(SchoolTestMakerService), new Uri(endpointAddress));
//Console.WriteLine(((WSDualHttpBinding)serviceHost.Description.Endpoints[0].Binding).Security.Message.ClientCredentialType);
serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = userNamePasswordValidator;
/*var externalAuthorizationPolicies = new ReadOnlyCollection<IAuthorizationPolicy>(new IAuthorizationPolicy[] { authorizationPolicy });
ServiceAuthorizationBehavior authorizationBehavior=serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
authorizationBehavior.ExternalAuthorizationPolicies = externalAuthorizationPolicies;*/
serviceHost.Open();
ServiceRunning = true;
}
答案 0 :(得分:0)
如果要使用自定义UserNamePassword验证,则必须告诉WCF哪个类将处理验证:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomUsernamePasswordAuth.Service.UserNamePassValidator, CustomUsernamePasswordAuth.Service" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>