Mam problem z połączeniem się z moją usługą WCF pod numerem clientCredentialType="UserName"
.Uwierzytelnianie WCF - Wystąpił błąd podczas sprawdzania zabezpieczeń wiadomości
Kiedy uruchomić poniższy kod pojawia się błąd
FaultException: Wystąpił błąd podczas weryfikacji bezpieczeństwa dla wiadomości.
Podczas gry z niektórymi wartościami wiążącymi otrzymuję również Access is denied.
.
Fiddler mówi, że nie ma nagłówka autoryzacji i nie mogę znaleźć nazwy użytkownika lub hasła w żądaniu.
Oto fragmenty z mojego config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<services>
<service name="InventoryServices.MobileAPI" behaviorConfiguration="customBehaviour">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="InventoryServices.IMobileAPI"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="customBehaviour">
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="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>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="InventoryLibrary.Helpers.UserAuthentication,InventoryLibrary"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="MyRealm"/>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
Mój login/hasło walidator wygląda tak:
public class UserAuthentication : UserNamePasswordValidator {
public override void Validate(string userName, string password) {
EntitiesContext db = new EntitiesContext();
db.Logs.Add(new DomainModels.Log() {
DateLogged = DateTime.Now,
Message = "hit auth",
Type = DomainModels.LogType.Info
});
db.SaveChanges();
try {
if (userName == "test" && password == "test123") {
Console.WriteLine("Authentic User");
}
}
catch (Exception ex) {
throw new FaultException("Unknown Username or Incorrect Password");
}
}
}
mam to za pomocą prostego testu na moją usługę:
[OperationContract]
[XmlSerializerFormat]
void Test();
[PrincipalPermission(SecurityAction.Demand, Name = "test")]
public void Test() {
}
Posiadam własny podpisany certyfikat SSL na moim serwerze i mogę uzyskać dostęp do mojej usługi/metadanych.
Potem dodałem odniesienie usług w aplikacji konsoli i próbować połączyć się z usługą z tego kodu poniżej:
class Program {
static void Main(string[] args) {
Stuff.InitiateSSLTrust();
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.Realm = "MyRealm";
ServiceReference1.MobileAPIClient serviceProxy = new ServiceReference1.MobileAPIClient(binding, new EndpointAddress("https://xx.xx.xx.xx/InventoryServices.MobileApi.svc"));
serviceProxy.ClientCredentials.UserName.UserName = "test";
serviceProxy.ClientCredentials.UserName.Password = "test123";
try {
var a = serviceProxy.Login("a", "b");
}
catch (Exception ex) {
var ex2 = ex;
}
}
}
public class Stuff {
public static void InitiateSSLTrust() {
try {
//Change SSL checks so that all checks pass
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(
delegate { return true; }
);
}
catch (Exception ex) {
}
}
}
Sprawdziłem Podglądu zdarzeń na serwerze i pojawia się ten błąd z każde żądanie:
MessageSecurityException: Procesor zabezpieczeń nie mógł znaleźć nagłówka zabezpieczeń w wiadomości. Może to być spowodowane tym, że wiadomość jest niezabezpieczoną usterką lub z powodu niedopasowania powiązania między komunikującymi się stronami. Może się tak zdarzyć, jeśli usługa jest skonfigurowana pod kątem bezpieczeństwa, a klient nie korzysta z zabezpieczeń.
Co Web klient/app.config wygląda? Powinno być tam kilka wartości dla certyfikatu dla powiązania zabezpieczenia wiadomości. Czy masz poprawnie ustawione uprawnienia do magazynu certyfikatów na serwerze? (Myślę, że jest to zazwyczaj "Mój" sklep z certyfikatami.Brzmi to bardzo podobnie do problemów, które miałem w przeszłości i jest brzydkim gwoździem. Próbuję to przypomnieć, kiedy piszę. Może powstać w ciągu następnych 10, podczas gdy ja o tym myślę. – brumScouse
Niestety nie widziałem, że powiązanie serwera było TransportWithMessage. Zauważyłem jednak, że twój klient korzystał tylko z powiązania transportu, które nie ma takiego samego powiązania jak serwer? – brumScouse