SecurityTokenHandler.WriteToken Method (XmlWriter, SecurityToken)

.NET Framework (current version)

The .NET API Reference documentation has a new home. Visit the .NET API Browser on to see the new experience.

When overridden in a derived class, serializes the specified security token to XML. The token must be of the type processed by the derived class.

Namespace:   System.IdentityModel.Tokens
Assembly:  System.IdentityModel (in System.IdentityModel.dll)

public virtual void WriteToken(
	XmlWriter writer,
	SecurityToken token


Type: System.Xml.XmlWriter

The XML writer.

Type: System.IdentityModel.Tokens.SecurityToken

The token to serialize.

By default this method throws a NotImplementedException exception.

Override this method to provide the logic to serialize a security token to XML. If you override this method, you should also override the CanWriteToken property.

The following code shows how to override the WriteToken method to serialize a custom token. The code is taken from the Custom Token sample. This sample provides custom classes that enable processing of Simple Web Tokens (SWT). For information about this sample and other samples available for WIF and where to download them, see WIF Code Sample Index.

/// <summary>
/// Serializes the given SecurityToken to the XmlWriter.
/// </summary>
/// <param name="writer">XmlWriter into which the token is serialized.</param>
/// <param name="token">SecurityToken to be serialized.</param>
public override void WriteToken( XmlWriter writer, SecurityToken token )
    SimpleWebToken simpleWebToken = token as SimpleWebToken;
    if ( simpleWebToken == null )
        throw new SecurityTokenException("The given token is not of the expected type 'SimpleWebToken'.");

    string signedToken = null;

    if ( String.IsNullOrEmpty( simpleWebToken.SerializedToken ) )
        StringBuilder strBuilder = new StringBuilder();

        bool skipDelimiter = true;
        NameValueCollection tokenProperties = simpleWebToken.GetAllProperties();

        // remove the signature if present
        if ( String.IsNullOrEmpty( tokenProperties[SimpleWebTokenConstants.Signature] ) )
            tokenProperties.Remove( SimpleWebTokenConstants.Signature );

        foreach ( string key in tokenProperties.Keys )
            if ( tokenProperties[key] != null )
                if ( !skipDelimiter )
                    strBuilder.Append( ParameterSeparator );

                strBuilder.Append( String.Format(
                    HttpUtility.UrlEncode( key ),
                    HttpUtility.UrlEncode( tokenProperties[key] ) ) );

                skipDelimiter = false;

        string serializedToken = strBuilder.ToString();

        SimpleWebTokenKeyIdentifierClause clause = new SimpleWebTokenKeyIdentifierClause(simpleWebToken.Audience);
        InMemorySymmetricSecurityKey securityKey = null;
            securityKey = (InMemorySymmetricSecurityKey)this.Configuration.IssuerTokenResolver.ResolveSecurityKey(clause);
        catch (InvalidOperationException)
            throw new SecurityTokenValidationException("A Symmetric key was not found for the given key identifier clause.");

        // append the signature
        string signature = GenerateSignature( serializedToken, securityKey.GetSymmetricKey() );
        strBuilder.Append( String.Format(
                    HttpUtility.UrlEncode( SimpleWebTokenConstants.Signature ),
                    HttpUtility.UrlEncode( signature ) ) );

        signedToken = strBuilder.ToString();
        // reuse the stored serialized token if present
        signedToken = simpleWebToken.SerializedToken;

    string encodedToken = Convert.ToBase64String( Encoding.UTF8.GetBytes( signedToken ) );
    writer.WriteAttributeString("Id", "", token.Id);
    writer.WriteAttributeString( ValueType, SimpleWebTokenConstants.ValueTypeUri );
    writer.WriteAttributeString( EncodingType, Base64EncodingType );
    writer.WriteString( encodedToken );
/// <summary>
/// Generates an HMACSHA256 signature for a given string and key.
/// </summary>
/// <param name="unsignedToken">The token to be signed.</param>
/// <param name="signingKey">The key used to generate the signature.</param>
/// <returns>The generated signature.</returns>
protected static string GenerateSignature(string unsignedToken, byte[] signingKey)
    using (HMACSHA256 hmac = new HMACSHA256(signingKey))
        byte[] signatureBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));
        string signature = HttpUtility.UrlEncode(Convert.ToBase64String(signatureBytes));

        return signature;

.NET Framework
Available since 4.5
Return to top