How to: Create a Class Representing a Custom Security Token Service

The first step for issuing custom security tokens is to create a class that represents the custom security token service. Derive the class the SecurityTokenService class and override the IssueSecurityToken method. Optionally, override the virtual methods of the SecurityTokenService class whose names begin with Enforce and Verify that verify incoming and enforce outgoing security token requests meet the security token service's signature and encryption requirements.

To create a class that implements the security token service

  1. Add a new class to a project. Derive the class from the SecurityTokenService class.

    Public Class XmlTokenServiceHandler
        Inherits SecurityTokenService
    
    public class XmlTokenServiceHandler : SecurityTokenService
    
  2. Add the following Imports or using directives to the top of the file for the class.

    Imports System
    Imports System.Web.Services.Protocols
    Imports Microsoft.Web.Services2
    Imports Microsoft.Web.Services2.Security
    Imports Microsoft.Web.Services2.Security.Cryptography
    Imports Microsoft.Web.Services2.Security.Tokens
    
    using System;
    using System.Web.Services.Protocols;
    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Cryptography;
    using Microsoft.Web.Services2.Security.Tokens;
    
  3. Override the IssueSecurityToken method.

    The IssueSecurityToken method handles security token requests sent to the security token service and issues security tokens for requests deemed valid. The IssueSecurityToken method handles security token requests contained in <RequestSecurityToken> or <RequestSecurityTokenResponse> elements, as described in the WS-Trust specification.

    The following code example overrides the IssuerSecurityToken method.

    Protected Overrides Function IssueSecurityToken(ByVal request As _
        SecurityTokenMessage) As RequestSecurityTokenResponse
        If request Is Nothing Then
            Throw New ArgumentNullException("request")
        End If
    
        ' This implementation only supports security token
        ' requests within a <RequestSecurityToken> element.
        Dim rst As rst = request '
        If rst Is Nothing Then
            Throw New TrustFault(TrustFault.BadRequestMessage, _
            TrustFault.BadRequestCode, _
            New Exception("Only RequestSecurityToken is supported"))
        End If
    
        ' Verify the type of security token being requested is
        ' supported by this custom security token service. If the 
        ' type of security token being requested is null, then
        ' issue the security token supported by this security token
        ' service.
        If Not (rst.TokenType Is Nothing) AndAlso rst.TokenType <> _
            XmlTokenNames.TypeNames.TokenType Then
            Throw New TrustFault(TrustFault.BadRequestMessage, _
                TrustFault.BadRequestCode, 
                New Exception("This security token server only supports requests for contoso xml tokens."))
        End If
    
        ' Issue a security token.
                '
        ' Get the security token that signs the response to the
        ' security token request, which is known as the service token.
        Dim serviceToken As SecurityToken
        ServiceToken = CustomTokenIssuerConfiguration.ServiceTokens.RetrieveServiceToken(rst)
    
        ' Create a new instance of the security token to be issued.
        Dim issuedXmlToken As New XmlToken(serviceToken)
    
        ' Create a new instance of RequestSecurityTokenResponse,
        ' which represents the response to the security token request.
        Dim requestSecurityTokenResponse As New _
            requestSecurityTokenResponse(issuedXmlToken)
    
        ' Create a <ProofToken> element that contains the security
        ' token and the key associated with the security token.
        requestSecurityTokenResponse.RequestedProofToken = _
            New RequestedProofToken(CType(issuedXmlToken.Key, _
            SymmetricKeyAlgorithm).KeyBytes, MyBase.RequestSigningToken)
    
         ' Return the response to the security token request to the
         ' client.
         Return requestSecurityTokenResponse
    End Function
    
    protected override RequestSecurityTokenResponse
        IssueSecurityToken(SecurityTokenMessage request)
    {
        if ( request == null )
            throw new ArgumentNullException("request");
        // This implementation only supports security token
        // requests within a <RequestSecurityToken> element.
        RequestSecurityToken rst = request as RequestSecurityToken;
        if ( rst == null )
            throw new TrustFault(TrustFault.BadRequestMessage,
                TrustFault.BadRequestCode, 
                new Exception("Only RequestSecurityToken is supported"));
    
        // Verify the type of security token being requested is
        // supported by this custom security token service. If the 
        // type of security token being requested is null, then
        // issue the security token supported by this security token
        // service.
        if (rst.TokenType != null && rst.TokenType !=
            XmlTokenNames.TypeNames.TokenType)
            throw new TrustFault(TrustFault.BadRequestMessage,
                TrustFault.BadRequestCode,
                new Exception("This security token server only supports requests for contoso xml tokens."));
    
        // Issue a security token.
    
        // Get the security token that signs the response to the
        // security token request, which is known as the service token.
        SecurityToken serviceToken = CustomTokenIssuerConfiguration.ServiceTokens.RetrieveServiceToken(rst);
    
        // Create a new instance of the security token to be issued.
        XmlToken issuedXmlToken = new XmlToken(serviceToken);
    
        // Create a new instance of RequestSecurityTokenResponse,
        // which represents the response to the security token request.
        RequestSecurityTokenResponse requestSecurityTokenResponse = new
            RequestSecurityTokenResponse(issuedXmlToken);
    
        // Create a <ProofToken> element that contains the security
        // token and the key associated with the security token.
        requestSecurityTokenResponse.RequestedProofToken = new
            RequestedProofToken(
            ((SymmetricKeyAlgorithm)issuedXmlToken.Key).KeyBytes,
            base.RequestSigningToken);
    
         // Return the response to the security token request to the
         // client.
         return requestSecurityTokenResponse;
    }
    

Example

The following code example is a custom security token service that issues a custom XML security token.

Note

Because this code example demonstrates how to issue the custom XML security token in the CustomXmlSecurityToken QuickStart Samples sample, it relies on code within that sample in order to successfully compile that is not shown below.

Imports System
Imports System.Web.Services.Protocols
Imports Microsoft.Web.Services2
Imports Microsoft.Web.Services2.Security
Imports Microsoft.Web.Services2.Security.Cryptography
Imports Microsoft.Web.Services2.Security.Tokens
Namespace CustomXmlSecToken

    Public Class XmlTokenServiceHandler
       Inherits SecurityTokenService

    Protected Overrides Function IssueSecurityToken(ByVal request As _
        SecurityTokenMessage) As RequestSecurityTokenResponse
        If request Is Nothing Then
            Throw New ArgumentNullException("request")
        End If

        ' This implementation only supports security token
        ' requests within a <RequestSecurityToken> element.
        Dim rst As rst = request '
        If rst Is Nothing Then
            Throw New TrustFault(TrustFault.BadRequestMessage, _
            TrustFault.BadRequestCode, _
            New Exception("Only RequestSecurityToken is supported"))
        End If

        ' Verify the type of security token being requested is
        ' supported by this custom security token service. If the 
        ' type of security token being requested is null, then
        ' issue the security token supported by this security token
        ' service.
        If Not (rst.TokenType Is Nothing) AndAlso rst.TokenType <> _
            XmlTokenNames.TypeNames.TokenType Then
            Throw New TrustFault(TrustFault.BadRequestMessage, _
                TrustFault.BadRequestCode, 
                New Exception("This security token server only supports requests for contoso xml tokens."))
        End If

        ' Issue a security token.
            '
        ' Get the security token that signs the response to the
        ' security token request, which is known as the service token.
        Dim serviceToken As SecurityToken
        ServiceToken = CustomTokenIssuerConfiguration.ServiceTokens.RetrieveServiceToken(rst)

        ' Create a new instance of the security token to be issued.
        Dim issuedXmlToken As New XmlToken(serviceToken)

        ' Create a new instance of RequestSecurityTokenResponse,
        ' which represents the response to the security token request.
        Dim requestSecurityTokenResponse As New _
            requestSecurityTokenResponse(issuedXmlToken)

        ' Create a <ProofToken> element that contains the security
        ' token and the key associated with the security token.
        requestSecurityTokenResponse.RequestedProofToken = _
            New RequestedProofToken(CType(issuedXmlToken.Key, _
            SymmetricKeyAlgorithm).KeyBytes, MyBase.RequestSigningToken)

         ' Return the response to the security token request to the
         ' client.
         Return requestSecurityTokenResponse
    End Function
    End Class
End Namespace
namespace CustomXmlSecToken
{
    using System;
    using System.Web.Services.Protocols;
    using Microsoft.Web.Services2;
    using Microsoft.Web.Services2.Security;
    using Microsoft.Web.Services2.Security.Cryptography;
    using Microsoft.Web.Services2.Security.Tokens;

    public class XmlTokenServiceHandler : SecurityTokenService
    {
    protected override RequestSecurityTokenResponse
       IssueSecurityToken(SecurityTokenMessage request)
    {
        if ( request == null )
            throw new ArgumentNullException("request");
        // This implementation only supports security token
        // requests within a <RequestSecurityToken> element.
        RequestSecurityToken rst = request as RequestSecurityToken;
        if ( rst == null )
            throw new TrustFault(TrustFault.BadRequestMessage,
                TrustFault.BadRequestCode, 
                new Exception("Only RequestSecurityToken is supported"));

        // Verify the type of security token being requested is
        // supported by this custom security token service. If the 
        // type of security token being requested is null, then
        // issue the security token supported by this security token
        // service.
        if (rst.TokenType != null && rst.TokenType !=
            XmlTokenNames.TypeNames.TokenType)
            throw new TrustFault(TrustFault.BadRequestMessage,
                TrustFault.BadRequestCode,
                new Exception("This security token server only supports requests for contoso xml tokens."));

        // Issue a security token.

        // Get the security token that signs the response to the
        // security token request, which is known as the service token.
        SecurityToken serviceToken = CustomTokenIssuerConfiguration.ServiceTokens.RetrieveServiceToken(rst);
            
        // Create a new instance of the security token to be issued.
        XmlToken issuedXmlToken = new XmlToken(serviceToken);

        // Create a new instance of RequestSecurityTokenResponse,
        // which represents the response to the security token request.
        RequestSecurityTokenResponse requestSecurityTokenResponse = new
            RequestSecurityTokenResponse(issuedXmlToken);

        // Create a <ProofToken> element that contains the security
        // token and the key associated with the security token.
        requestSecurityTokenResponse.RequestedProofToken = new
            RequestedProofToken(
            ((SymmetricKeyAlgorithm)issuedXmlToken.Key).KeyBytes,
            base.RequestSigningToken);

         // Return the response to the security token request to the
         // client.
         return requestSecurityTokenResponse;
    }
    }
}

See Also

Tasks

How to: Configure a Custom Security Token Service

Reference

SecurityTokenService Class

Other Resources

Issuing Security Tokens