SpnegoTokenProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SpnegoTokenProvider.cs / 4 / SpnegoTokenProvider.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Security 
{
    using System; 
    using System.Collections; 
    using System.Xml;
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Net;
    using System.Security.Principal;
    using System.IdentityModel.Claims; 
    using System.IdentityModel.Policy;
    using System.ServiceModel; 
    using System.ServiceModel.Security.Tokens; 
    using System.Globalization;
    using System.Runtime.Serialization; 
    using System.ServiceModel.Diagnostics;

    using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials;
 
    class SpnegoTokenProvider : SspiNegotiationTokenProvider
    { 
        TokenImpersonationLevel allowedImpersonationLevel = TokenImpersonationLevel.Identification; 
        ICredentials clientCredential;
        IdentityVerifier identityVerifier = IdentityVerifier.CreateDefault(); 
        bool allowNtlm = true;
        bool authenticateServer = true;
        SafeFreeCredentials credentialsHandle;
        bool ownCredentialsHandle = false; 

        public SpnegoTokenProvider(SafeFreeCredentials credentialsHandle) 
            : base() 
        {
            this.credentialsHandle = credentialsHandle; 
        }

        // settings
        public IdentityVerifier IdentityVerifier 
        {
            get 
            { 
                return this.identityVerifier;
            } 
            set
            {
                this.CommunicationObject.ThrowIfDisposedOrImmutable();
                this.identityVerifier = value; 
            }
        } 
 
        public TokenImpersonationLevel AllowedImpersonationLevel
        { 
            get
            {
                return this.allowedImpersonationLevel;
            } 
            set
            { 
                this.CommunicationObject.ThrowIfDisposedOrImmutable(); 

                TokenImpersonationLevelHelper.Validate(value); 
                if (value == TokenImpersonationLevel.None)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value",
                        String.Format(CultureInfo.InvariantCulture, SR.GetString(SR.SpnegoImpersonationLevelCannotBeSetToNone)))); 
                }
                this.allowedImpersonationLevel = value; 
            } 
        }
 
        public ICredentials ClientCredential
        {
            get
            { 
                return this.clientCredential;
            } 
            set 
            {
                this.CommunicationObject.ThrowIfDisposedOrImmutable(); 
                this.clientCredential = value;
            }
        }
 
        public bool AllowNtlm
        { 
            get 
            {
                return this.allowNtlm; 
            }
            set
            {
                this.CommunicationObject.ThrowIfDisposedOrImmutable(); 
                this.allowNtlm = value;
            } 
        } 

        public bool AuthenticateServer 
        {
            get
            {
                return this.authenticateServer; 
            }
            set 
            { 
                this.CommunicationObject.ThrowIfDisposedOrImmutable();
                this.authenticateServer = value; 
            }
        }

        // overrides 
        public override XmlDictionaryString NegotiationValueType
        { 
            get 
            {
                return XD.TrustApr2004Dictionary.SpnegoValueTypeUri; 
            }
        }

        public override void OnOpening() 
        {
            bool osIsGreaterThanXP = SecurityUtils.IsOsGreaterThanXP(); 
 
            base.OnOpening();
            if (this.credentialsHandle == null) 
            {
                string packageName;
                if ( !this.allowNtlm && !osIsGreaterThanXP )
                { 
                    packageName = "Kerberos";
                } 
                else 
                {
                    packageName = "Negotiate"; 
                }

                NetworkCredential credential = null;
                if (this.clientCredential != null) 
                {
                    credential = this.clientCredential.GetCredential(this.TargetAddress.Uri, packageName); 
                } 

                // if OS is less than 2k3 !NTLM is not supported, Windows SE 142400 
                if (!this.allowNtlm && osIsGreaterThanXP)
                {
                    this.credentialsHandle = SecurityUtils.GetCredentialsHandle(packageName, credential, false, "!NTLM");
                } 
                else
                { 
                    this.credentialsHandle = SecurityUtils.GetCredentialsHandle(packageName, credential, false); 
                }
 
                this.ownCredentialsHandle = true;
            }
        }
 
        public override void OnClose(TimeSpan timeout)
        { 
            base.OnClose(timeout); 
            FreeCredentialsHandle();
        } 

        public override void OnAbort()
        {
            base.OnAbort(); 
            FreeCredentialsHandle();
        } 
 
        void FreeCredentialsHandle()
        { 
            if (this.credentialsHandle != null)
            {
                if (this.ownCredentialsHandle)
                { 
                    this.credentialsHandle.Close();
                } 
                this.credentialsHandle = null; 
            }
        } 

        protected override bool CreateNegotiationStateCompletesSynchronously(EndpointAddress target, Uri via)
        {
            return true; 
        }
 
        protected override IAsyncResult BeginCreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout, AsyncCallback callback, object state) 
        {
            SspiNegotiationTokenProviderState sspiState = this.CreateNegotiationState(target, via, timeout); 
            return new TypedCompletedAsyncResult(sspiState, callback, state);
        }

        protected override SspiNegotiationTokenProviderState EndCreateNegotiationState(IAsyncResult result) 
        {
            return TypedCompletedAsyncResult.End(result); 
        } 

        protected override SspiNegotiationTokenProviderState CreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout) 
        {
            EnsureEndpointAddressDoesNotRequireEncryption(target);

            EndpointIdentity identity = null; 
            if (this.identityVerifier == null)
            { 
                identity = target.Identity; 
            }
            else 
            {
                this.identityVerifier.TryGetIdentity(target, out identity);
            }
 
            string spn;
            if (this.AuthenticateServer || !this.AllowNtlm) 
            { 
                spn = SecurityUtils.GetSpnFromIdentity(identity, target);
            } 
            else
            {
                // if an SPN or UPN identity is configured (for example, in mixed mode SSPI), then
                // use that identity for Negotiate 
                Claim identityClaim = identity.IdentityClaim;
                if (identityClaim != null && (identityClaim.ClaimType == ClaimTypes.Spn || identityClaim.ClaimType == ClaimTypes.Upn)) 
                { 
                    spn = identityClaim.Resource.ToString();
                } 
                else
                {
                    spn = "host/" + target.Uri.DnsSafeHost;
                } 
            }
 
            string packageName; 
            if ( !this.allowNtlm && !SecurityUtils.IsOsGreaterThanXP() )
            { 
                packageName = "Kerberos";
            }
            else
            { 
                packageName = "Negotiate";
            } 
 
            WindowsSspiNegotiation sspiNegotiation = new WindowsSspiNegotiation(packageName, this.credentialsHandle,
                this.AllowedImpersonationLevel, spn, true); 
            return new SspiNegotiationTokenProviderState(sspiNegotiation);
        }

        protected override ReadOnlyCollection ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation) 
        {
            WindowsSspiNegotiation windowsNegotiation = (WindowsSspiNegotiation)sspiNegotiation; 
            if (windowsNegotiation.IsValidContext == false) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation))); 
            }
            if (this.AuthenticateServer && windowsNegotiation.IsMutualAuthFlag == false)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.CannotAuthenticateServer))); 
            }
            SecurityTraceRecordHelper.TraceClientSpnego(windowsNegotiation); 
 
            return SecurityUtils.CreatePrincipalNameAuthorizationPolicies(windowsNegotiation.ServicePrincipalName);
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK