none
WSE 2.0 WSE405: A satisfactory subset of policy assertions that could be enforced for the outgoing message could not be found RRS feed

  • Question

  • I'm developing WSE 2.0 Client for Web Service (ERCOT API) in Visual Studio using Console Application, and I had guideline to follow, so I think I followed it exactly, but I'm encountering error. 


    I have following error message:
    --------------------------------

        "Error Message :WSE405: A satisfactory subset of policy assertions
         that could be enforced for the outgoing message could not be found."

    I enabled the logging and SendPolicy.webinfo file have this error in it:

        <log xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wssp="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy" xmlns:wset="http://schemas.microsoft.com/wse/2003/09/PolicyTrace">
          <wset:message action="/BusinessService/NodalService.serviceagent/HttpEndPoint/MarketInfo" messageId="uuid:52be4340-f886-47b6-b053-3bcbf532b9dd" appDomain="ERCOT_WebService_WSE.vshost.exe" time="2014-01-10T10:21:38.0999620-06:00">
            <wset:compile qname="wsp:Policy" wsu:Id="#Sign-X.509" usage="Required" canEnforce="false">
              <wset:compile qname="wsp:MessagePredicate" usage="Required" canEnforce="true" />
              <wset:compile qname="wssp:Integrity" usage="Required" canEnforce="false">
                <wset:annotation>ISecurityTokenManager.PermitsPolicyEnforcementTokenCaching is set to true in the token manager registered for this token type. A token will be loaded from the token manager and cached for subsequent message enforcement.</wset:annotation>
                <wset:annotation>Invoking ISecurityTokenManager.LoadTokenFromSecurityTokenAssertion from the token manager registered for this token type.</wset:annotation>
                <wset:annotation>Could not find a security token.</wset:annotation>
                <wset:annotation>Looking for a satisfactory token in the current message's token collection...</wset:annotation>
                <wset:annotation>Looking for a satisfactory token in policy enforcement token cache...</wset:annotation>
                <wset:annotation>ISecurityTokenManager.PermitsPolicyEnforcementTokenCaching is set to true in the token manager registered for this token type. Attempting to use the previously cached token...</wset:annotation>
                <wset:annotation>Invoking ISecurityTokenManager.LoadTokenFromSecurityTokenAssertion from the token manager registered for this token type.</wset:annotation>
                <wset:annotation>Could not find a security token.</wset:annotation>
              </wset:compile>
            </wset:compile>
          </wset:message>
        </log>

    It says "Could not find a security token." in integerity section of policyCache.config, so I'm guessing it's related to not finding certificate, but I have no progress so far beyond this error. I tried to change policyCahche config file and app.config file, move around certificates, changing store name, modifying code, but so can't get through this error.

    Here initial set up.
    ----------------------------------------

     1. Installed Visual Studio 2008 Express.
     2. Checked to make sure .NET 3.5 is installed.
     3. Installed WSE 2.0 SP3.
     4. Added SDK Bin directory to PATH: C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin
     5. Obtained Client API Certificate and Server Public Key Certificate - ERCOT Public Key (valid from 10/01/2012 to 09/07/2015) Link: http://www.ercot.com/content/services/mdt/webservices/certs/misapi.ercot.com_public_key_new.zip
     6. Downloaded WSDL for the Web Service.

    *For a note: My operating system is Windows 8.*

    Here is the procedure I followed to get WSE 2.0 Client:
    ---------------------------------------------------

    1. Open Visual Studio 2008
    2. Create a new console project
    3. Add Reference to Microsoft.Web.Services2
    4. Add Web Reference 
    -  Select nodal.wsdl
    - Generate stubbed classes
    - Edit generated classes
        -   Inherit service from Microsoft.web.Services2.WebServicesClientProtocol
        -   Modify XML serialization for outbound requests
    5.  Edit Program.cs to make web service call.
    - Ensure client certificates are in place
    - Ensure callback handlers for server authentication are in place
    6. Configure policy using WSE 2.0 Configurator tool
    - Modify policy.cache to remove assertions

    I did not know what "Modify XML serialization for outbound requests" meant, so I skipped that step. I was unsure of what "Modify policy.cache to remove assertions" meant also, but I thought it was just removing assertion of message part and message predicate in policyCache.config to only sign portion of it.


    Config files and Code
    ---------------------

    I'm posting policyCache.config file, app.config file, and Program.cs file for WSE 2.0 Client.

    Here is my policyCache.config file (confidential info changed):

        <?xml version="1.0" encoding="utf-8"?>
        <policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
          <mappings xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy">
            <!--The following policy describes the policy requirements for the service: https://my.endpointaddress.com/my/end/point/here/ .-->
            <endpoint uri="https://my.endpointaddress.com/my/end/point/here/">
              <defaultOperation>
                <request policy="#Sign-X.509" />
                <response policy="#Sign-X.509-1" />
                <fault policy="" />
              </defaultOperation>
            </endpoint>
          </mappings>
          <policies xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wssp="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
            <wsp:Policy wsu:Id="Sign-X.509">
              <!--MessagePredicate is used to require headers. This assertion should be used along with the Integrity assertion when the presence of the signed element is required. NOTE: this assertion does not do anything for enforcement (send-side) policy.-->
              <wsp:MessagePredicate wsp:Usage="wsp:Required" Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body() wsp:Header(wsa:To) wsp:Header(wsa:Action) wsp:Header(wsa:MessageID) wse:Timestamp()</wsp:MessagePredicate>
              <!--The Integrity assertion is used to ensure that the message is signed with X.509. Many Web services will also use the token for authorization, such as by using the <wse:Role> claim or specific X.509 claims.-->
              <wssp:Integrity wsp:Usage="wsp:Required">
                <wssp:TokenInfo>
                  <!--The SecurityToken element within the TokenInfo element describes which token type must be used for Signing.-->
                  <wssp:SecurityToken>
                    <wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
                    <wssp:TokenIssuer>ClientCertificateIssuer</wssp:TokenIssuer>
                    <wssp:Claims>
                      <!--By specifying the SubjectName claim, the policy system can look for a certificate with this subject name in the certificate store indicated in the application's configuration, such as LocalMachine or CurrentUser. The WSE X.509 Certificate Tool is useful for finding the correct values for this field.-->
                      <wssp:SubjectName MatchType="wssp:Exact">ClientCertificateSubjectName</wssp:SubjectName>
                      <wssp:X509Extension OID="2.5.29.14" MatchType="wssp:Exact">ClientCertificateEncryptedHash</wssp:X509Extension>
                    </wssp:Claims>
                  </wssp:SecurityToken>
                </wssp:TokenInfo>
                <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body() wsp:Header(wsa:Action) wsp:Header(wsa:FaultTo) wsp:Header(wsa:From) wsp:Header(wsa:MessageID) wsp:Header(wsa:RelatesTo) wsp:Header(wsa:ReplyTo) wsp:Header(wsa:To) wse:Timestamp()</wssp:MessageParts>
              </wssp:Integrity>
            </wsp:Policy>
            <wsp:Policy wsu:Id="Sign-X.509-1">
              <!--MessagePredicate is used to require headers. This assertion should be used along with the Integrity assertion when the presence of the signed element is required. NOTE: this assertion does not do anything for enforcement (send-side) policy.-->
              <wsp:MessagePredicate wsp:Usage="wsp:Required" Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body() wsp:Header(wsa:To) wsp:Header(wsa:Action) wsp:Header(wsa:MessageID) wse:Timestamp()</wsp:MessagePredicate>
              <!--The Integrity assertion is used to ensure that the message is signed with X.509. Many Web services will also use the token for authorization, such as by using the <wse:Role> claim or specific X.509 claims.-->
              <wssp:Integrity wsp:Usage="wsp:Required">
                <wssp:TokenInfo>
                  <!--The SecurityToken element within the TokenInfo element describes which token type must be used for Signing.-->
                  <wssp:SecurityToken>
                    <wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
                    <wssp:TokenIssuer>ServerCertificateIssuer</wssp:TokenIssuer>
                    <wssp:Claims>
                      <!--By specifying the SubjectName claim, the policy system can look for a certificate with this subject name in the certificate store indicated in the application's configuration, such as LocalMachine or CurrentUser. The WSE X.509 Certificate Tool is useful for finding the correct values for this field.-->
                      <wssp:SubjectName MatchType="wssp:Exact">ServerCertificateSubjectName</wssp:SubjectName>
                      <wssp:X509Extension OID="2.5.29.14" MatchType="wssp:Exact">ServerCertificateEncryptedHash</wssp:X509Extension>
                    </wssp:Claims>
                  </wssp:SecurityToken>
                </wssp:TokenInfo>
                <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body() wsp:Header(wsa:Action) wsp:Header(wsa:FaultTo) wsp:Header(wsa:From) wsp:Header(wsa:MessageID) wsp:Header(wsa:RelatesTo) wsp:Header(wsa:ReplyTo) wsp:Header(wsa:To) wse:Timestamp()</wssp:MessageParts>
              </wssp:Integrity>
            </wsp:Policy>
          </policies>
        </policyDocument>


    Here is my app.config file (confidential info changed):

        <?xml version="1.0" encoding="utf-8"?>
        <configuration>
          <configSections>
            <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
              <section name="ERCOT_WebService_WSE.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
            </sectionGroup>
            <section name="microsoft.web.services2" type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
          </configSections>
          <applicationSettings>
            <ERCOT_WebService_WSE.Properties.Settings>
              <setting name="ERCOT_WebService_WSE_WebReference_NodalService" serializeAs="String">
                <value>https://my.endpointaddress.com/my/end/point/here/</value>
              </setting>
            </ERCOT_WebService_WSE.Properties.Settings>
          </applicationSettings>
          <microsoft.web.services2>
            <security>
              <x509 storeLocation="LocalMachine" />
            </security>
            <diagnostics>
              <trace enabled="true" input="C:\directoryToProject\...\InputTrace.webinfo" output="C:\directoryToProject\...\OutputTrace.webinfo" />
              <policyTrace enabled="true" input="C:\directoryToProject\...\ReceivePolicy.webinfo" output="C:\directoryToProject\...\SendPolicy.webinfo" />
              <detailedErrors enabled="true" />
            </diagnostics>
            <policy>
              <cache name="policyCache.config" />
            </policy>
          </microsoft.web.services2>
        </configuration>

    Here is my Program.cs file  (confidential info changed):

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using ERCOT_WebService_WSE.WebReference;
        using System.Security.Cryptography;
        using System.Net;
        using System.Net.Security;
        using System.Security.Cryptography.X509Certificates;
        
        namespace ERCOT_WebService_WSE
        {
            class Program
            {
                static void Main(string[] args)
                {
                    try
                    {
                        NodalService nodalService = new NodalService();
                        
                        String certSubjectString = "APICertificateSubjectName";
        
                        X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                        X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySerialNumber, certSubjectString, true);
                        X509Certificate certificate = null;
                        foreach (X509Certificate cert in store.Certificates)
                        {
                            if (cert.Subject.Contains(certSubjectString))
                            {
                                certificate = cert;
                                break;
                            }
                        }
                        nodalService.ClientCertificates.Add(certificate);
                        ServicePointManager.ServerCertificateValidationCallback = TrustAllCertificateCallback;
        
                        RequestMessage requestMessage = new RequestMessage();
                        ResponseMessage responseMsg = new ResponseMessage();
        
                        //Header
                        HeaderType header = new HeaderType();
                        header.Verb = HeaderTypeVerb.get;
                        header.Noun = "SystemStatus";
                        header.Revision = "1";
                        header.Source = "0000000000000";
                        header.UserID = "API_UserName";
        
                        //Replay Detection
                        ReplayDetectionType repDetection = new ReplayDetectionType();
                        EncodedString encodedStr = new EncodedString();
                        encodedStr.Value = "6666666666";
                        repDetection.Nonce = encodedStr;
                        repDetection.Created = new AttributedDateTime();
        
                        header.ReplayDetection = repDetection;
        
                        //Payload
                        String payloadMsg = "VERIFY";
                        requestMessage.Payload = new PayloadType();
                        requestMessage.Payload.format = payloadMsg;
                        requestMessage.Header = header;
        
                        Console.WriteLine("Request Message " + requestMessage.Payload.format);
        
                        //calling the web service here.
                        responseMsg = nodalService.MarketInfo(requestMessage);
        
                        if (payloadMsg == "VERIFY")
                        {
                            Console.WriteLine("Successfully connected to the service and the response is " + responseMsg.Header.Comment);
                        }
                        else if (payloadMsg == "NOTIFY")
                        {
                            Console.WriteLine("Successfully connected to the service and the response is " + responseMsg.Reply.ReplyCode);
                        }
        
                        //wait for user
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error Message :" + ex.Message);
                        Console.ReadLine();
                    }
                }
                public static bool TrustAllCertificateCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors errors)
                {
                    return true;
                }
            }
        }

    I also have Reference.cs file (generated using WSDL file as Web Reference), but it's too long, so I will just post what I edited:

        //I changed System.Web.Services.Protocols.SoapHttpClientProtocol to Microsoft.Web.Services2.WebServicesClientProtocol
        public partial class NodalService : Microsoft.Web.Services2.WebServicesClientProtocol {

    -------------------------------
    How would I fix this W405 error? 
    Is this certificate pointing issue or is it some other issue? 
    If it is certificate pointing issue, how can I make sure the certificate is in place?

    One strange thing is that this same code passed policy assertion error yesterday night, but just for only once, after that we get same error WSE405. The new error in the trace log was fault message with

        <SOAP-ENV:Body wsu:Id="_0a51911e-3313bpdbqf-3bb6">
          <SOAP-ENV:Fault>
            <faultcode xmlns="">SOAP-ENV:Server</faultcode>
            <faultstring xmlns="">This is an operation implementation generated fault</faultstring>
            <faultactor xmlns="" />
            <detail xmlns="">
              <ns:FaultMessage xmlns:ns="http://www.ercot.com/schema/2007-06/nodal/ews/message" xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <ns:Reply>
                  <ns:ReplyCode>ERROR</ns:ReplyCode>
                  <ns:Error>Error encountered when interacting with the ReplayDetection service in the MarketTransactions Adapter.</ns:Error>
                  <ns:Timestamp>2014-01-09T19:52:12.843-06:00</ns:Timestamp>
                </ns:Reply>
              </ns:FaultMessage>
            </detail>
          </SOAP-ENV:Fault>
        </SOAP-ENV:Body>

    Any help or suggestion would be greatly appreciated. Thank you.
    Friday, January 10, 2014 7:45 PM

Answers