File: System\ServiceModel\MessageSecurityOverHttp.cs
Web Access
Project: src\src\System.ServiceModel.Http\src\System.ServiceModel.Http.csproj (System.ServiceModel.Http)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Runtime;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;
 
namespace System.ServiceModel
{
    public class MessageSecurityOverHttp
    {
        internal const MessageCredentialType DefaultClientCredentialType = MessageCredentialType.Windows;
        internal const bool DefaultNegotiateServiceCredential = true;
 
        private MessageCredentialType _clientCredentialType;
        private SecurityAlgorithmSuite _algorithmSuite;
        private bool _wasAlgorithmSuiteSet;
 
        public MessageSecurityOverHttp()
        {
            _clientCredentialType = DefaultClientCredentialType;
            NegotiateServiceCredential = DefaultNegotiateServiceCredential;
            _algorithmSuite = SecurityAlgorithmSuite.Default;
        }
 
        public MessageCredentialType ClientCredentialType
        {
            get { return _clientCredentialType; }
            set
            {
                if (!MessageCredentialTypeHelper.IsDefined(value))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(value)));
                }
 
                _clientCredentialType = value;
            }
        }
        public bool NegotiateServiceCredential { get; set; }
 
        public SecurityAlgorithmSuite AlgorithmSuite
        {
            get { return _algorithmSuite; }
            set
            {
                _algorithmSuite = value ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value));
                _wasAlgorithmSuiteSet = true;
            }
        }
 
        protected virtual bool IsSecureConversationEnabled()
        {
            return true;
        }
 
        internal SecurityBindingElement CreateSecurityBindingElement(bool isSecureTransportMode, bool isReliableSession, MessageSecurityVersion version)
        {
            if (isReliableSession && !IsSecureConversationEnabled())
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.SecureConversationRequiredByReliableSession));
            }
 
            SecurityBindingElement result;
            SecurityBindingElement oneShotSecurity;
 
            bool isKerberosSelected = false;
            if (isSecureTransportMode)
            {
                switch (_clientCredentialType)
                {
                    case MessageCredentialType.None:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ClientCredentialTypeMustBeSpecifiedForMixedMode));
                    case MessageCredentialType.UserName:
                        oneShotSecurity = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
                        break;
                    case MessageCredentialType.Certificate:
                        oneShotSecurity = SecurityBindingElement.CreateCertificateOverTransportBindingElement();
                        break;
                    case MessageCredentialType.Windows:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
                    case MessageCredentialType.IssuedToken:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
                    default:
                        Fx.Assert("unknown ClientCredentialType");
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
                }
 
                if (IsSecureConversationEnabled())
                {
                    result = SecurityBindingElement.CreateSecureConversationBindingElement(oneShotSecurity, true);
                }
                else
                {
                    result = oneShotSecurity;
                }
            }
            else
            {
                throw ExceptionHelper.PlatformNotSupported();
            }
 
            // set the algorithm suite and issued token params if required
            if (_wasAlgorithmSuiteSet || (!isKerberosSelected))
            {
                result.DefaultAlgorithmSuite = oneShotSecurity.DefaultAlgorithmSuite = AlgorithmSuite;
            }
            else if (isKerberosSelected)
            {
                throw ExceptionHelper.PlatformNotSupported();
            }
 
            result.IncludeTimestamp = true;
            oneShotSecurity.MessageSecurityVersion = version;
            result.MessageSecurityVersion = version;
            if (!isReliableSession)
            {
                result.LocalClientSettings.ReconnectTransportOnFailure = false;
            }
            else
            {
                result.LocalClientSettings.ReconnectTransportOnFailure = true;
            }
 
            return result;
        }
    }
}