Share via


How to: Verify Digital Signatures of SOAP Messages Signed Using a Kerberos Ticket

WSE validates a digital signature for cryptographic correctness, but user code should be used to verify that a signature exists and that the signature applies to the expected set of XML elements. When WSE is configured to run with the recipient, signature validation is done by WSE before recipient code executes.

To configure WSE to validate digital signatures for incoming SOAP messages

  • In the Web.config file for the Web application that is hosting the Web service, include an <soapServerProtocolFactory> Element element in the <webServices> section.

    When the SOAP message recipient is a Web service client, this configuration entry is not required. Instead, the base class that the proxy class derives from must be changed to derive from the WebServicesClientProtocol.

    The following code example shows the configuration entry that must be placed in the Web.config file for WSE to run with a Web service. The type attribute of the <soapServerProtocolFactory> Element element must be on one line, even though the following sample shows it split across multiple lines for readability.

    <configuration>
       <system.web>
            <webServices>
                <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
            </webServices>
        </system.web>
       </system.web>
    </configuration>
    

To use code to require that incoming SOAP messages are signed using a Kerberos token and that the required XML elements are signed

  1. Create a custom policy assertion.

    For more details about creating custom policy assertions, see How to: Create a Custom Policy Assertion that Secures SOAP Messages.

  2. In the input SOAP filter for the client or the Web service that receives the signed SOAP messages, override the ValidateMessageSecurity method.

    The following code example overrides the ValidateMessageSecurity method for the Web service input SOAP filter.

    Public Overrides Sub ValidateMessageSecurity(ByVal envelope As SoapEnvelope, ByVal security As Security)
    
    public override void ValidateMessageSecurity(SoapEnvelope envelope, Security security)
    {
    
  3. Verify that the expected XML elements for SOAP requests are signed using a KerberosToken security token.

    The following code example verifies that a digital signature exists for a SoapContext and that it signed the <Body> element.

    Dim IsSigned As Boolean = False
    Dim element As ISecurityElement
    For Each element In security.Elements
        If (TypeOf (element) Is MessageSignature) Then
            ' The SoapContext contains a Signature element. 
            Dim sig As MessageSignature = element
            Dim expectedOptions As SignatureOptions = SignatureOptions.IncludeTimestamp Or _
                                                      SignatureOptions.IncludeSoapBody Or _
                                                      SignatureOptions.IncludeTo Or _
                                                      SignatureOptions.IncludeAction Or _
                                                      SignatureOptions.IncludeMessageId
    
            If ((sig.SignatureOptions And expectedOptions) = expectedOptions) Then
                ' The SOAP body and the WS-Addressing headers are signed.
                If (TypeOf sig.SigningToken Is KerberosToken) Then
                    ' The SOAP message is signed by a KerberosToken.
                    IsSigned = True
                End If
            End If
        End If
    Next
    If (Not IsSigned) Then
        Throw New SecurityFault("Message did not meet security requirements.")
    
    bool IsSigned = false;
    foreach (ISecurityElement element in security.Elements)
    {
        if (element is MessageSignature)
        {
            // The given context contains a Signature element.
            MessageSignature sig = element as MessageSignature;
            SignatureOptions expectedOptions = SignatureOptions.IncludeTimestamp |
                                               SignatureOptions.IncludeSoapBody |
                                               SignatureOptions.IncludeTo |
                                               SignatureOptions.IncludeAction |
                                               SignatureOptions.IncludeMessageId;
            if ((sig.SignatureOptions & expectedOptions) == expectedOptions)
            {
                // The SOAP message is signed.
                if (sig.SigningToken is KerberosToken)
                    // The SOAP message is signed by a X509SecurityToken.
                    IsSigned = true;
            }
        }
    }
    if (!IsSigned)
        throw new SecurityFault("Message did not meet security requirements.");
    

Example

The following code example defines a Web service method that verifies that requests are made using SOAP and that the <Body> element and WS-Addressing headers are signed using a KerberosToken security token.

Public Overrides Sub ValidateMessageSecurity(ByVal envelope As SoapEnvelope, ByVal security As Security)
    Dim IsSigned As Boolean = False
    Dim element As ISecurityElement
    For Each element In security.Elements
        If (TypeOf (element) Is MessageSignature) Then
            ' The SoapContext contains a Signature element. 
            Dim sig As MessageSignature = element
            Dim expectedOptions As SignatureOptions = SignatureOptions.IncludeTimestamp Or _
                                                      SignatureOptions.IncludeSoapBody Or _
                                                      SignatureOptions.IncludeTo Or _
                                                      SignatureOptions.IncludeAction Or _
                                                      SignatureOptions.IncludeMessageId

            If ((sig.SignatureOptions And expectedOptions) = expectedOptions) Then
                ' The SOAP body and the WS-Addressing headers are signed.
                If (TypeOf sig.SigningToken Is KerberosToken) Then
                    ' The SOAP message is signed by a KerberosToken.
                    IsSigned = True
                End If
            End If
        End If
    Next
    If (Not IsSigned) Then
        Throw New SecurityFault("Message did not meet security requirements.")
    End If
End Sub 'ValidateMessageSecurity
public override void ValidateMessageSecurity(SoapEnvelope envelope, Security security)
{
    bool IsSigned = false;
    foreach (ISecurityElement element in security.Elements)
    {
        if (element is MessageSignature)
        {
            // The given context contains a Signature element.
            MessageSignature sig = element as MessageSignature;
            SignatureOptions expectedOptions = SignatureOptions.IncludeTimestamp |
                                               SignatureOptions.IncludeSoapBody |
                                               SignatureOptions.IncludeTo |
                                               SignatureOptions.IncludeAction |
                                               SignatureOptions.IncludeMessageId;
            if ((sig.SignatureOptions & expectedOptions) == expectedOptions)
            {
                // The SOAP message is signed.
                if (sig.SigningToken is KerberosToken)
                    // The SOAP message is signed by a X509SecurityToken.
                    IsSigned = true;
            }
        }
    }
    if (!IsSigned)
        throw new SecurityFault("Message did not meet security requirements.");
}

See Also

Tasks

How to: Sign a SOAP Message By Using a Kerberos Ticket

Reference

KerberosToken

Other Resources

Kerberos Ticket
Brokered Authentication – Kerberos
Kerberos Technical Supplement for Windows