How to: Determine Which Parts of a SOAP Message Were Signed or Encrypted
WSE allows a SOAP message recipient to programmatically determine the portions of the SOAP message that were signed or encrypted. By default, if the SOAP message sender is using WSE, WSE encrypts the entire contents of the <Body> element and none of the SOAP headers. For digital signing, WSE signs the entire contents of the <Body> element, the <Timestamp> element of the Security header, and all addressing headers. However, the sender need not be using WSE, and even if they are, these default settings can be overridden. For details about overriding the default WSE settings, see How to: Specify the Parts of a SOAP Message That Are Signed or Encrypted.
To determine which parts of a SOAP message were signed
Receive the SOAP message.
If the recipient is a Web service, the code with the Web service method executes when a SOAP message is received. If the recipient is a Web service client, then the code executes when a SOAP response is received.
Iterate over the Elements collection of the Security property of the SoapContext.
The following code example iterates over the SoapContext for a SOAP request received by a Web service.
Dim context As SoapContext = RequestSoapContext.Current Dim element As ISecurityElement For Each element In context.Security.Elements
SoapContext context = RequestSoapContext.Current; foreach (ISecurityElement element in context.Security.Elements)
Determine whether the object implementing the ISecurityElement interface is an instance of the MessageSignature class.
The following code example checks whether the object is an instance of MessageSignature.
If TypeOf element Is MessageSignature Then
if ( elment is MessageSignature)
Determine which of WSE default elements were signed in this SOAP message.
The SignatureOptions property of the MessageSignature class is a bit field that specifies the elements of a SOAP message that are signed by default.
The following code example checks whether the <Body> element is signed.
Dim bodySigned As Boolean = _ ((sig.SignatureOptions And SignatureOptions.IncludeSoapBody)<> 0)
bool bodySigned = ((sig.SignatureOptions & SignatureOptions.IncludeSoapBody) != 0);
Determine if any elements are signed that are not signed by WSE by default.
The following code example iterates over the nondefault elements, if any, that were signed.
Dim i As Integer For i = 0 To sig.SignedInfo.References.Count – 1 Next i
for(int i = 0; i < sig.SignedInfo.References.Count; i++)
To determine which parts of a SOAP message were encrypted
Receive the SOAP message.
If the recipient is a Web service, the code with the Web service method executes when a SOAP message is received. If the recipient is a Web service client, then the code executes when a SOAP response is received.
Iterate over the Elements collection of the Security property of the SoapContext.
The following code example iterates over the SoapContext for a SOAP response received by a Web service client. The
proxy
variable is an instance of the proxy class to the Web service.Dim element As ISecurityElement For Each element In context.Security.Elements Next
foreach (ISecurityElement element in context.Security.Elements)
Determine whether the object implementing the ISecurityElement interface is an instance of the EncryptedData class.
For each element of the SOAP message that is encrypted, there is an instance of EncryptedData in the Elements collection.
The following code example checks whether the object is an instance of EncryptedData.
If TypeOf element Is EncryptedData Then
if ( element is EncryptedData)
Determine which element that is encrypted.
The following code example checks whether the <Body> element is encrypted.
Dim encryptedData As encryptedData = element Dim targetElement As System.Xml.XmlElement = encryptedData.TargetElement If (SoapEnvelope.IsSoapBody(targetElement)) Then ' The given context has the Body element Encrypted. Return encryptedData.SecurityToken End If
EncryptedData encryptedData = element as EncryptedData; System.Xml.XmlElement targetElement = encryptedData.TargetElement; if ( SoapEnvelope.IsSoapBody(targetElement)) { // The given context has the Body element Encrypted. return encryptedData.SecurityToken; }
Example
The following code example verifies that the <Body> element and the To, Action, MessageID, and From headers are signed using a UsernameToken security token.
Private Function IsMessageSigned(ByVal context As SoapContext) As Boolean
Dim element As ISecurityElement
For Each element In context.Security.Elements
If (TypeOf (element) Is MessageSignature) Then
' The SoapContext contains a MessageSignature element.
Dim sign As MessageSignature = element
If ((sign.SignatureOptions And _
(SignatureOptions.IncludeSoapBody Or _
SignatureOptions.IncludeTo Or _
SignatureOptions.IncludeAction Or _
SignatureOptions.IncludeMessageId Or _
SignatureOptions.IncludeFrom)) = _
(SignatureOptions.IncludeSoapBody Or _
SignatureOptions.IncludeTo Or _
SignatureOptions.IncludeAction Or _
SignatureOptions.IncludeMessageId Or _
SignatureOptions.IncludeFrom)) Then
If TypeOf sign.SigningToken Is UsernameToken Then
' The SOAP message is signed with a
' UsernameToken.
Return True
End If
End If
End If
Next
Return False
End Function
private bool IsMessageSigned(SoapContext context)
{
foreach (ISecurityElement element in context.Security.Elements)
{
if (element is MessageSignature)
{
MessageSignature sign = element as MessageSignature;
if ((sign.SignatureOptions &
(SignatureOptions.IncludeSoapBody |
SignatureOptions.IncludeTo |
SignatureOptions.IncludeAction |
SignatureOptions.IncludeMessageId |
SignatureOptions.IncludeFrom)) ==
(SignatureOptions.IncludeSoapBody |
SignatureOptions.IncludeTo |
SignatureOptions.IncludeAction |
SignatureOptions.IncludeMessageId |
SignatureOptions.IncludeFrom))
{
// The SOAP message is signed.
if (sign.SigningToken is UsernameToken)
// The SOAP message is signed
// with a UsernameToken.
return true;
}
}
}
return false;
}
The following code example checks whether the <Body> element of a SOAP message is encrypted given a SoapContext.
Public Shared Function GetEncryptingToken(ByVal context As SoapContext) As SecurityToken
Dim element As ISecurityElement
For Each element In context.Security.Elements
If (TypeOf (element) Is encryptedData) Then
Dim encryptedData As encryptedData = element
Dim targetElement As System.Xml.XmlElement = encryptedData.TargetElement
If (SoapEnvelope.IsSoapBody(targetElement)) Then
' The given context has the Body element Encrypted.
Return encryptedData.SecurityToken
End If
End If
Next
Return Nothing
End Function 'GetEncryptingToken
public static SecurityToken GetEncryptingToken(SoapContext context)
{
foreach (ISecurityElement element in context.Security.Elements)
{
if (element is EncryptedData)
{
EncryptedData encryptedData = element as EncryptedData;
System.Xml.XmlElement targetElement = encryptedData.TargetElement;
if ( SoapEnvelope.IsSoapBody(targetElement))
{
// The given context has the Body element Encrypted.
return encryptedData.SecurityToken;
}
}
}
return null;
}
See Also
Tasks
How to: Specify the Parts of a SOAP Message That Are Signed or Encrypted
How to: Digitally Sign a SOAP Message
How to: Encrypt a SOAP Message