Export (0) Print
Expand All

<kerberosSecurity> Element

Represents a turnkey security assertion that uses a KerberosToken security token to authenticate the client and protect SOAP messages.

<policies> Element
  <policy> Element (Policy)

<kerberosSecurity
  clientActor
  establishSecurityContext="true|false"
  messageProtectionOrder="Signature and encryption order"
  renewExpiredSecurityContext="true|false"
  requireDerivedKeys="true|false"
  requireSignatureConfirmation="true|false"
  serviceActor
  ttlInSeconds >
  <token/>
  <protection/>
</kerberosSecurity>

Microsoft.Web.Services3.Design.KerberosAssertion

Attributes

Attribute Description

clientActor

Optional attribute. Specifies the actor attribute on the Security SOAP header for a SOAP message that is destined for a Web service client to which this policy assertion applies. When the SOAP message is not routed through an intermediary, such as a SOAP router, the actor attribute is an empty string (""). When the policy assertion applies to an intermediary, specify the URI for the intermediary. The default value is an empty string ("").

establishSecurityContext

Optional attribute. Specifies whether a secure conversation is established using SecurityContextToken security tokens. Possible values are true and false. true specifies that this security assertion secures the security token request and its response (the RST and RSTR) and SOAP messages exchanged between the client and the Web service are secured using SecurityContextToken security tokens. The default value is false.

Note:
The establishSecurityContext attribute cannot be set to true when stateful SecurityContextToken security tokens are used. In this scenario, the RST and RSTR are secured using a KerberosToken security token that is also placed in the state of the issued SecurityContextToken security token. KerberosToken security tokens are based on Security Support Provider Interface (SSPI) Kerberos tokens that can be used once and only once. When the KerberosToken is part of the SecurityContextToken security token's state, the SSPI Kerberos token is used every time the SecurityContextToken security token is used. SSPI throws an exception when it is used more than once. Therefore, the establishSecurityContext attribute can only be set to true for the <kerberosSecurity> turnkey security assertion when stateful SecurityContextToken security tokens are not used. To specify whether stateful SecurityContextToken security tokens are used, use the <statefulSecurityContextToken> Element.

messageProtectionOrder

Optional attribute. Specifies the order of operation for digital signatures and message encryption. SignBeforeEncrypting specifies that a digital signature is generated for the SOAP message before any portion of the SOAP message is encrypted, but the digital signature is not encrypted. SignBeforeEncryptingAndEncryptSignature specifies that a digital signature is generated for the SOAP message before any portion of the SOAP message is encrypted and the digital signature is encrypted.

renewExpiredSecurityContext

Optional attribute. Specifies that a new SecurityContextToken security token is automatically requested as the current one expires when a secure conversation is established. This is applicable only when the establishSecurityContext attribute for this policy assertion is true.

requireDerivedKeys

Optional attribute. Specifies whether DerivedKeyToken security tokens are used. Possible values are true and false.

requireSignatureConfirmation

Optional attribute. Specifies whether the Web service sends a confirmation that verifies the client's digital signature and whether the client rejects SOAP responses without a signature confirmation. This is always false.

serviceActor

Optional attribute. Specifies the actor attribute on the Security SOAP header for a SOAP message destined for a Web service to which this policy assertion applies. When the SOAP message is not routed through an intermediary, such as a SOAP router, the actor attribute is an empty string (""). When the policy assertion applies to an intermediary, specify the URI for the intermediary. The default value is an empty string ("").

Note:
When the serviceActor attribute is set to a value other than an empty string (""), then the establishSecurityContext attribute must be set to false.

ttlInSeconds

Optional attribute. Specifies the default number of seconds that a SOAP message is valid after its creation. The default value is 5 minutes (300 seconds).

Child Elements

Element Description

<token> Element

Optional element. Specifies the details for the KerberosToken security token. If the details of the KerberosToken security token are not specified in the policy file, the security token must be added using code.

<protection> Element

Optional element. Specifies the portions of the SOAP message that are signed, encrypted, or both.

Parent Elements

Element Description

<policy> Element

Specifies a SOAP message requirement.

This security assertion can have zero or more <protection> elements. Use more than one <protection> element to apply protection requirements for each operation using the requestAction attribute. Each of the <protection> elements must have a unique requestAction attribute unless the requestAction is omitted. Only one of the <protection> elements can omit the requestAction attribute, and that element defines the default protection requirements for the policy.

WSE 3.0 works on Windows Server 2000; however a custom policy assertion is required for WSE 3 clients or WSE 3 Web services that are hosted on Windows Server 2000. When a SOAP message is encrypted or digitally signed by a Kerberos ticket, the recipient must obtain the session key to encrypt or decrypt the SOAP message or to validate the digital signature. Windows Server 2000 prevents applications from obtaining the session key for a Kerberos ticket, so it is not possible to digitally sign or encrypt a SOAP message using a Kerberos ticket on Windows Server 2000. Kerberos tickets can still be used for authentication on Windows Server 2000, however. See the code example in the Code section of this topic for an example custom policy assertion that authenticates the client using a Kerberos ticket, but does not protect the SOAP message.

SOAP requests sent by the client and SOAP responses sent by the Web service are protected as specified in the following table.

SOAP message Protection Description

SOAP request

Digital Signature

The SOAP message parts specified in the <request> child element of the <protection> element are digitally signed using a KerberosToken security token.

SOAP request

Encryption

The SOAP message parts specified in the <request> child element of the <protection> element are encrypted using an KerberosToken security token.

SOAP response

Digital Signature

The SOAP message parts specified in the <response> or <fault> child elements of the <protection> element are digitally signed using the KerberosToken security token that encrypted the SOAP request.

SOAP response

Encryption

The SOAP message parts specified in the <response> or <fault> child elements of the <protection> element are encrypted using the KerberosToken security token that encrypted the SOAP request.

The following code example demonstrates how to secure a SOAP message exchange using a KerberosToken security token. The code example defines a policy assertion named kerberosAuthenticationKerberosProtection that specifies that a KerberosToken security token is used to authenticate the client, digitally signs the SOAP message, and encrypts the <body> element of the SOAP message. The keys used to generate the digital signature and encrypt the <body> element are not the same keys, but rather are derived from the same key.

<policies>
  <extensions>
    <extension name="kerberosSecurity"
               type="Microsoft.Web.Services3.Design.KerberosAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <extension name="kerberos"
               type="Microsoft.Web.Services3.Design.KerberosTokenProvider, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <extension name="requireActionHeader"
               type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </extensions>
  <policy name="kerberosAuthenticationKerberosProtection">
    <kerberosSecurity establishSecurityContext="false" signatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypting" requireDerivedKeys="true">
      <token>
        <kerberos targetPrincipal="host/contoso4@contoso.com" impersonationLevel="Identification" />
      </token>
      <protection>
        <request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
        <response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="true" />
        <fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
      </protection>
    </kerberosSecurity>
    <requireActionHeader />
  </policy>
</policies>

The following code example is a custom policy assertion that authenticates a client or Web service using a Kerberos ticket where the SOAP messages are not protected by a Kerberos ticket. Applications should modify this custom policy assertion to provide an alternative mechanism for protecting the SOAP messages. For more details about creating a custom policy assertion that secures a SOAP message, see How to: Create a Custom Policy Assertion that Secures SOAP Messages.


using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;

using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Design;
using Microsoft.Web.Services3.Security;
using Microsoft.Web.Services3.Security.Tokens;


namespace TestPolicyAssertion
{
enum MessageType
{
TokenOnly,
TokenWithSignatureAndEncryption
}

class CustomKerberosAssertion : KerberosAssertion
{
MessageType incomingMessageType;
public CustomKerberosAssertion()
: base()
{
}

public override SoapFilter CreateClientOutputFilter(FilterCreationContext context)
{
return new CustomClientOutputFilter(this);
}

public override SoapFilter CreateClientInputFilter(FilterCreationContext context)
{
return new CustomClientInputFilter(this);
}

public override SoapFilter CreateServiceInputFilter(FilterCreationContext context)
{
return new CustomServiceInputFilter(this);
}

public override SoapFilter CreateServiceOutputFilter(FilterCreationContext context)
{
return new CustomServiceOutputFilter(this);
}

public MessageType IncomingMsgType
{
get { return this.incomingMessageType; }
set { this.incomingMessageType = value; }
}

protected class CustomServiceInputFilter : KerberosAssertion.ServiceInputFilter
{
CustomKerberosAssertion assertion;
public CustomServiceInputFilter(CustomKerberosAssertion assertion)
: base(assertion)
{
this.assertion = assertion;
}

public override void ValidateMessageSecurity(SoapEnvelope envelope, Security security, MessageProtectionRequirements request)
{
if (security == null)
throw new SecurityFault("Incoming request does not contain a security header.");

if (security.Elements.Count > 0)
{
// The SOAP request came from a client that is running Windows Server 2003.
// NOTE: Set the message type first, in case the base.Validate throws an exception,
// because the code needs to specify which assertion to use to secure
// the outgoing message.
this.assertion.IncomingMsgType = MessageType.TokenWithSignatureAndEncryption;
base.ValidateMessageSecurity(envelope, security, request);
}
else
{
// The SOAP request came from a client that is running Windows 2000.
this.assertion.IncomingMsgType = MessageType.TokenOnly;

// Try and get the Kerberos token in the tokens collection.
KerberosToken kerberosToken = null;
if (!TryGetUniqueKerberosToken(security.Tokens, out kerberosToken))
{
if (kerberosToken == null)
{
throw new SecurityFault(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Could not find the Kerberos Token in the incoming message."));
}
else
{
throw new SecurityFault(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Multiple Kerberos Tokens found in the incoming message."));
}
}

string serviceActor = this.GetServiceActor(envelope.CurrentSoap);
envelope.Context.Credentials.SetCredentials(new CredentialSet(kerberosToken), serviceActor);
// Set the IdentityToken when this message is for the ultimate destination.
if (serviceActor == String.Empty)
envelope.Context.IdentityToken = kerberosToken;
}
}

bool TryGetUniqueKerberosToken(SecurityTokenCollection tokens, out KerberosToken kerbToken)
{
kerbToken = null;
foreach (SecurityToken token in tokens)
{
if (token is KerberosToken)
{
if (kerbToken == null)
{
kerbToken = (KerberosToken)token;
}
else
{
// This is a second Kerberos token and is therefore not unique.
return false;
}
}
}

return kerbToken != null;
}
}

protected class CustomServiceOutputFilter : KerberosAssertion.ServiceOutputFilter
{
CustomKerberosAssertion assertion;
public CustomServiceOutputFilter(CustomKerberosAssertion assertion)
: base(assertion)
{
this.assertion = assertion;
}

public override void SecureMessage(SoapEnvelope envelope, Security security, MessageProtectionRequirements response)
{
// Secure the outgoing response only when  the incoming
// message is signed and encrypted.
if (assertion.IncomingMsgType == MessageType.TokenWithSignatureAndEncryption)
{
base.SecureMessage(envelope, security, response);
}
}
}

/// This class is the client output filter for Windows 2000 clients.
/// The outgoing message only contains the Kerberos token and is not signed
/// or encrypted by the Kerberos token.
protected class CustomClientOutputFilter : KerberosAssertion.ClientOutputFilter
{
TokenProvider<KerberosToken> provider;
KerberosToken kerberosToken;

public CustomClientOutputFilter(KerberosAssertion assertion)
: base(assertion)
{
provider = assertion.KerberosTokenProvider;
}

public override void SecureMessage(SoapEnvelope envelope, Security security, MessageProtectionRequirements request)
{
if (envelope == null)
throw new ArgumentNullException("envelope");
if (security == null)
throw new SecurityFault(String.Format(System.Globalization.CultureInfo.InvariantCulture, "No security header was found while verifying the incoming message"));
if (request == null)
throw new ArgumentNullException("request");

if (provider != null)
this.kerberosToken = provider.GetToken();

KerberosToken kt = GetClientToken(this.kerberosToken, this.GetServiceActor(envelope.CurrentSoap));
security.Tokens.Add(kt);
}

KerberosToken GetClientToken(KerberosToken token, string actor)
{
if (token != null)
return token;

KerberosToken result = null;

if (actor != null && SoapContext.Current != null)
{
CredentialSet cs = SoapContext.Current.Credentials[actor];
result = cs.GetServiceToken<KerberosToken>();
}

if (result == null)
throw new InvalidOperationException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Unable to determine service token to use. Service token type requested was '{0}'. The token must be provided either through policy by specifying the token in the policy assertion or through code by calling WebServicesClientProtocol.SetCredentials or using properties on the SoapContext.Credentials.", typeof(KerberosToken).ToString()));

return result;
}
}

protected class CustomClientInputFilter : KerberosAssertion.ClientInputFilter
{
public CustomClientInputFilter(KerberosAssertion assertion)
: base(assertion)
{
}

public override void ValidateMessageSecurity(SoapEnvelope envelope, Security security, MessageProtectionRequirements response)
{
if (envelope == null)
throw new ArgumentNullException("envelope");
if (security == null)
throw new SecurityFault(String.Format(System.Globalization.CultureInfo.InvariantCulture, "No security header was found while verifying the incoming message"));
}

public override IEnumerable<SecurityToken> GetUnattachedTokensCore(SoapContext context)
{
return null;
}
}
}
}
    
Show:
© 2014 Microsoft