How to: Authorize the Message Sender Based on a Kerberos Ticket

WSE enables you to authorize access to a Web service method based on a Kerberos ticket (KerberosToken security token) within a SOAP message. When a SOAP message is received, WSE attempts to authenticate the SOAP message sender. If authentication succeeds, the Principal property of the KerberosToken security token is assigned a principal representing the authenticated user.

For an overview of authorization support in WSE, see Authorizing Access to a Web Service.

The following procedures detail how to use code to authorize access to a Web service by using a Kerberos service ticket. Whether you use policy or code, WSE must be enabled to process the incoming SOAP messages.

To configure WSE to process 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 authorize access to a Web service method by using a Kerberos service ticket

  1. Add code to the Web service method that obtains the KerberosToken security token that the application wants to use for authentication and authorization.

    A SOAP message can contain multiple security tokens, which might sign or encrypt different portions of the SOAP message. Therefore, it is up to the application to determine which security token is used for authorization.

    The following code example defines, and then calls a GetBodySigningToken method that obtains the KerberosToken security token that signed the <Body> element of the SOAP request.

        Public Function GetBodySigningToken(ByVal requestContext As SoapContext) As KerberosToken
            Dim token As KerberosToken = Nothing
            Dim securityElement As ISecurityElement
            For Each securityElement In requestContext.Security.Elements
                If (TypeOf securityElement Is MessageSignature) Then
                    Dim sig As MessageSignature = _
                        CType(securityElement, MessageSignature)
                    If ((sig.SignatureOptions And _
                        SignatureOptions.IncludeSoapBody) <> 0) Then
                        Dim sigToken As SecurityToken = sig.SigningToken
                        If (TypeOf sigToken Is KerberosToken) Then
                            token = CType(sigToken, KerberosToken)
                        End If
                    End If
                End If
            Next
            Return token
        End Function
    
    
    
    ...
    
    
                ' Get the KerberosToken security token that was used to sign the SOAP
            ' request.
            Dim token As KerberosToken = GetBodySigningToken(requestContext)
    
        public KerberosToken GetBodySigningToken(SoapContext requestContext)
        {
            KerberosToken token = null;
            foreach (ISecurityElement securityElement in
                requestContext.Security.Elements)
            {
                if (securityElement is MessageSignature)
                {
                    MessageSignature sig =
                        (MessageSignature)securityElement;
                    if ((sig.SignatureOptions &
                        SignatureOptions.IncludeSoapBody) != 0)
                    {
                        SecurityToken sigToken = sig.SigningToken;
                        if (sigToken is KerberosToken)
                            token = (KerberosToken)sigToken;
                    }
                }
            }
            return token;
        }
    
    
    
    ...
    
    
                // Get the KerberosToken security token that was used to sign the SOAP
            // request.
            KerberosToken token = GetBodySigningToken(requestContext);
    
  2. Ensure that the user is a member of the role or roles authorized to call this Web service method.

    The following code example ensures a KerberosToken security token was used to sign the SOAP message and that the user is a member of the Tellers role.

    If (token Is Nothing OrElse Not token.Principal.IsInRole("Tellers")) Then
        Throw New UnauthorizedAccessException
    End If
    
    if (token == null || !token.Principal.IsInRole("Tellers"))
        throw new UnauthorizedAccessException();
    

Example

The following code example authorizes SOAP requests to the SayHello Web service in which a KerberosToken security token signs the SOAP <Body> element and the user is a member of the Tellers role.

Imports System
Imports System.Web.Services

Imports Microsoft.Web.Services3
Imports Microsoft.Web.Services3.Security
Imports Microsoft.Web.Services3.Security.Tokens

Namespace KerbAuth
    <WebService()> _
    Public Class Service1
        <WebMethod()> _
        Public Function SayHello() As String
            ' Ensure that the request is a SOAP request.
            Dim requestContext As SoapContext = RequestSoapContext.Current
            If requestContext Is Nothing Then
                Throw New ApplicationException("Only SOAP requests are permitted.")
            End If

            ' Get the KerberosToken security token that was used to sign the SOAP
            ' request.
            Dim token As KerberosToken = GetBodySigningToken(requestContext)
            If (token Is Nothing OrElse Not token.Principal.IsInRole("Tellers")) Then
                Throw New UnauthorizedAccessException
            End If
            Return "Hello World"
        End Function

        Public Function GetBodySigningToken(ByVal requestContext As SoapContext) As KerberosToken
            Dim token As KerberosToken = Nothing
            Dim securityElement As ISecurityElement
            For Each securityElement In requestContext.Security.Elements
                If (TypeOf securityElement Is MessageSignature) Then
                    Dim sig As MessageSignature = _
                        CType(securityElement, MessageSignature)
                    If ((sig.SignatureOptions And _
                        SignatureOptions.IncludeSoapBody) <> 0) Then
                        Dim sigToken As SecurityToken = sig.SigningToken
                        If (TypeOf sigToken Is KerberosToken) Then
                            token = CType(sigToken, KerberosToken)
                        End If
                    End If
                End If
            Next
            Return token
        End Function
    End Class
End Namespace
using System;
using System.Web.Services;

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

namespace KerbAuth
{
    [WebService]
    public class Service1
    {
        [WebMethod]
        public string SayHello()
        {
            // Ensure that the request is a SOAP request.
            SoapContext requestContext = RequestSoapContext.Current;
            if (requestContext == null)
                throw new ApplicationException("Only SOAP requests are permitted.");
                
            // Get the KerberosToken security token that was used to sign the SOAP
            // request.
            KerberosToken token = GetBodySigningToken(requestContext);

            if (token == null || !token.Principal.IsInRole("Tellers"))
                throw new UnauthorizedAccessException();
            return "Hello World";
        }

        public KerberosToken GetBodySigningToken(SoapContext requestContext)
        {
            KerberosToken token = null;
            foreach (ISecurityElement securityElement in
                requestContext.Security.Elements)
            {
                if (securityElement is MessageSignature)
                {
                    MessageSignature sig =
                        (MessageSignature)securityElement;
                    if ((sig.SignatureOptions &
                        SignatureOptions.IncludeSoapBody) != 0)
                    {
                        SecurityToken sigToken = sig.SigningToken;
                        if (sigToken is KerberosToken)
                            token = (KerberosToken)sigToken;
                    }
                }
            }
            return token;
        }
    }
}

See Also

Other Resources

Kerberos Ticket
Brokered Authentication – Kerberos
Kerberos Technical Supplement for Windows