我在使用clientCredentialType="UserName"
連接到我的WCF服務時遇到問題。WCF身份驗證 - 驗證郵件安全性時出錯
當我運行下面的代碼,我得到一個錯誤
的FaultException:該消息確認安全時發生錯誤。
當玩弄一些綁定值時,我也得到Access is denied.
。
Fiddler說沒有授權頭,我也找不到請求中的用戶名或密碼。
下面是我的配置摘錄:
<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>
我的用戶名/密碼驗證程序看起來像這樣:
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");
}
}
}
我這是對我的服務進行簡單的測試:
[OperationContract]
[XmlSerializerFormat]
void Test();
[PrincipalPermission(SecurityAction.Demand, Name = "test")]
public void Test() {
}
我在我的服務器上有一個自簽名的SSL證書,我可以訪問我的服務/元數據。
然後我加入了一個控制檯應用程序的服務引用,並嘗試用下面這段代碼連接到服務:
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) {
}
}
}
我檢查事件查看器在服務器上,並出現此錯誤每個請求:
MessageSecurityException:安全處理器無法在消息中找到安全標頭。這可能是因爲該消息是不安全的錯誤,或者是因爲通信雙方之間存在綁定不匹配。如果服務配置了安全性並且客戶端沒有使用安全性,則會發生這種情況。
什麼是您的客戶端web/app.config中是什麼樣子?對於那裏的證書應該有一些值用於消息安全綁定。另外,您是否擁有正確的服務器設置上的證書存儲權限? (我認爲它通常是「我的」證書商店。這聽起來與我過去遇到的問題非常相似,並且是一個難題。我正在嘗試在我輸入時回顧它。這可能會在接下來的10年中形成,而我想到它。 – brumScouse
對不起,我沒有看到服務器綁定是TransportWithMessage。但是,我確實注意到您的客戶端只使用與服務器綁定不同的傳輸綁定? – brumScouse