< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Security.NegotiationTokenAuthenticator<T>
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/NegotiationTokenAuthenticator.cs
Line coverage
39%
Covered lines: 148
Uncovered lines: 227
Coverable lines: 375
Total lines: 944
Line coverage: 39.4%
Branch coverage
13%
Covered branches: 19
Total branches: 140
Branch coverage: 13.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Security/NegotiationTokenAuthenticator.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.Globalization;
 8using System.Threading;
 9using System.Threading.Tasks;
 10using System.Xml;
 11using CoreWCF.Channels;
 12using CoreWCF.Description;
 13using CoreWCF.Diagnostics;
 14using CoreWCF.Dispatcher;
 15using CoreWCF.IdentityModel.Policy;
 16using CoreWCF.IdentityModel.Tokens;
 17using CoreWCF.Runtime;
 18using CoreWCF.Security.Tokens;
 19
 20namespace CoreWCF.Security
 21{
 22    internal abstract class NegotiationTokenAuthenticator<T> : CommunicationObjectSecurityTokenAuthenticator, IIssuanceS
 23        where T : NegotiationTokenAuthenticatorState
 24    {
 25        internal const string DefaultServerMaxNegotiationLifetimeString = "00:01:00";
 26        internal const string DefaultServerIssuedTokenLifetimeString = "10:00:00";
 27        internal const string DefaultServerIssuedTransitionTokenLifetimeString = "00:15:00";
 28        internal const int DefaultServerMaxActiveNegotiations = 128;
 129        internal static readonly TimeSpan s_defaultServerMaxNegotiationLifetime = TimeSpan.Parse(DefaultServerMaxNegotia
 130        internal static readonly TimeSpan s_defaultServerIssuedTransitionTokenLifetime = TimeSpan.Parse(DefaultServerIss
 31        internal const int DefaultServerMaxCachedTokens = 1000;
 32        internal const bool DefaultServerMaintainState = true;
 133        internal static readonly SecurityStandardsManager s_defaultStandardsManager = SecurityStandardsManager.DefaultIn
 134        internal static readonly SecurityStateEncoder s_defaultSecurityStateEncoder = new DataProtectionSecurityStateEnc
 35        private NegotiationTokenAuthenticatorStateCache<T> _stateCache;
 36        private NegotiationHost _negotiationHost;
 37        private bool _encryptStateInServiceToken;
 38        private TimeSpan _serviceTokenLifetime;
 39        private int _maximumCachedNegotiationState;
 40        private TimeSpan _negotiationTimeout;
 41        private bool _isClientAnonymous;
 42        private SecurityStandardsManager _standardsManager;
 43        private SecurityAlgorithmSuite _securityAlgorithmSuite;
 44        private SecurityTokenParameters _issuedSecurityTokenParameters;
 45        private ISecurityContextSecurityTokenCache _issuedTokenCache;
 46        private BindingContext _issuerBindingContext;
 47        private Uri _listenUri;
 48
 49        // AuditLogLocation auditLogLocation;
 50        private bool _suppressAuditFailure;
 51
 52        // AuditLevel messageAuthenticationAuditLevel;
 53        private SecurityStateEncoder _securityStateEncoder;
 54        private SecurityContextCookieSerializer _cookieSerializer;
 55        private IMessageFilterTable<EndpointAddress> _endpointFilterTable;
 56        private int _maxMessageSize;
 57        private IList<Type> _knownTypes;
 58        private int _maximumConcurrentNegotiations;
 59        private List<IChannel> _activeNegotiationChannels1;
 60        private List<IChannel> _activeNegotiationChannels2;
 61        private IOThreadTimer _idlingNegotiationSessionTimer;
 62        private bool _isTimerCancelled;
 63
 264        protected NegotiationTokenAuthenticator() : base() => InitializeDefaults();
 65
 066        public IssuedSecurityTokenHandler IssuedSecurityTokenHandler { get; set; }
 67
 068        public RenewedSecurityTokenHandler RenewedSecurityTokenHandler { get; set; }
 69
 70        // settings
 71        public bool EncryptStateInServiceToken
 72        {
 073            get => _encryptStateInServiceToken;
 74            set
 75            {
 176                CommunicationObject.ThrowIfDisposedOrImmutable();
 177                _encryptStateInServiceToken = value;
 178            }
 79        }
 80
 81        public TimeSpan ServiceTokenLifetime
 82        {
 083            get => _serviceTokenLifetime;
 84            set
 85            {
 186                CommunicationObject.ThrowIfDisposedOrImmutable();
 187                if (value <= TimeSpan.Zero)
 88                {
 089                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val
 90                }
 91
 192                if (TimeoutHelper.IsTooLarge(value))
 93                {
 094                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val
 095                        SR.Format(SRCommon.SFxTimeoutOutOfRangeTooBig)));
 96                }
 197                _serviceTokenLifetime = value;
 198            }
 99        }
 100
 101        public int MaximumCachedNegotiationState
 102        {
 1103            get => _maximumCachedNegotiationState;
 104            set
 105            {
 1106                CommunicationObject.ThrowIfDisposedOrImmutable();
 1107                if (value < 0)
 108                {
 0109                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val
 110                }
 1111                _maximumCachedNegotiationState = value;
 1112            }
 113        }
 114
 115        public int MaximumConcurrentNegotiations
 116        {
 0117            get => _maximumConcurrentNegotiations;
 118            set
 119            {
 1120                CommunicationObject.ThrowIfDisposedOrImmutable();
 1121                if (value < 0)
 122                {
 0123                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val
 124                }
 1125                _maximumConcurrentNegotiations = value;
 1126            }
 127        }
 128
 129        public TimeSpan NegotiationTimeout
 130        {
 1131            get => _negotiationTimeout;
 132            set
 133            {
 1134                CommunicationObject.ThrowIfDisposedOrImmutable();
 1135                if (value <= TimeSpan.Zero)
 136                {
 0137                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val
 138                }
 139
 1140                if (TimeoutHelper.IsTooLarge(value))
 141                {
 0142                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val
 0143                        SR.Format(SRCommon.SFxTimeoutOutOfRangeTooBig)));
 144                }
 1145                _negotiationTimeout = value;
 1146            }
 147        }
 148
 149        public bool IsClientAnonymous
 150        {
 0151            get => _isClientAnonymous;
 152            set
 153            {
 1154                CommunicationObject.ThrowIfDisposedOrImmutable();
 1155                _isClientAnonymous = value;
 1156            }
 157        }
 158
 159        public SecurityAlgorithmSuite SecurityAlgorithmSuite
 160        {
 1161            get => _securityAlgorithmSuite;
 162            set
 163            {
 1164                CommunicationObject.ThrowIfDisposedOrImmutable();
 1165                _securityAlgorithmSuite = value;
 1166            }
 167        }
 168
 169        public IMessageFilterTable<EndpointAddress> EndpointFilterTable
 170        {
 0171            get => _endpointFilterTable;
 172            set
 173            {
 0174                CommunicationObject.ThrowIfDisposedOrImmutable();
 0175                _endpointFilterTable = value;
 0176            }
 177        }
 178
 0179        ISecurityContextSecurityTokenCache ISecurityContextSecurityTokenCacheProvider.TokenCache => IssuedTokenCache;
 180
 0181        public virtual XmlDictionaryString RequestSecurityTokenAction => StandardsManager.TrustDriver.RequestSecurityTok
 182
 0183        public virtual XmlDictionaryString RequestSecurityTokenResponseAction => StandardsManager.TrustDriver.RequestSec
 184
 0185        public virtual XmlDictionaryString RequestSecurityTokenResponseFinalAction => StandardsManager.TrustDriver.Reque
 186
 187        public SecurityStandardsManager StandardsManager
 188        {
 1189            get => _standardsManager;
 190            set
 191            {
 1192                CommunicationObject.ThrowIfDisposedOrImmutable();
 1193                _standardsManager = (value ?? SecurityStandardsManager.DefaultInstance);
 1194            }
 195        }
 196
 197        public SecurityTokenParameters IssuedSecurityTokenParameters
 198        {
 1199            get => _issuedSecurityTokenParameters;
 200            set
 201            {
 1202                CommunicationObject.ThrowIfDisposedOrImmutable();
 1203                _issuedSecurityTokenParameters = value;
 1204            }
 205        }
 206
 207        public ISecurityContextSecurityTokenCache IssuedTokenCache
 208        {
 1209            get => _issuedTokenCache;
 210            set
 211            {
 1212                CommunicationObject.ThrowIfDisposedOrImmutable();
 1213                _issuedTokenCache = value;
 1214            }
 215        }
 216
 217        //public AuditLogLocation AuditLogLocation
 218        //{
 219        //    get
 220        //    {
 221        //        return this.auditLogLocation;
 222        //    }
 223        //    set
 224        //    {
 225        //        this.CommunicationObject.ThrowIfDisposedOrImmutable();
 226        //        this.auditLogLocation = value;
 227        //    }
 228        //}
 229
 230        public bool SuppressAuditFailure
 231        {
 0232            get => _suppressAuditFailure;
 233            set
 234            {
 0235                CommunicationObject.ThrowIfDisposedOrImmutable();
 0236                _suppressAuditFailure = value;
 0237            }
 238        }
 239
 240        //public AuditLevel MessageAuthenticationAuditLevel
 241        //{
 242        //    get
 243        //    {
 244        //        return this.messageAuthenticationAuditLevel;
 245        //    }
 246        //    set
 247        //    {
 248        //        this.CommunicationObject.ThrowIfDisposedOrImmutable();
 249        //        this.messageAuthenticationAuditLevel = value;
 250        //    }
 251        //}
 252
 253        public BindingContext IssuerBindingContext
 254        {
 4255            get => _issuerBindingContext;
 256            set
 257            {
 1258                CommunicationObject.ThrowIfDisposedOrImmutable();
 1259                if (value == null)
 260                {
 0261                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value));
 262                }
 1263                _issuerBindingContext = value.Clone();
 1264            }
 265        }
 266
 267        public Uri ListenUri
 268        {
 1269            get => _listenUri;
 270            set
 271            {
 1272                CommunicationObject.ThrowIfDisposedOrImmutable();
 1273                _listenUri = value;
 1274            }
 275        }
 276
 277        public SecurityStateEncoder SecurityStateEncoder
 278        {
 2279            get => _securityStateEncoder;
 280            set
 281            {
 1282                CommunicationObject.ThrowIfDisposedOrImmutable();
 1283                _securityStateEncoder = value;
 1284            }
 285        }
 286
 287        public IList<Type> KnownTypes
 288        {
 1289            get => _knownTypes;
 290            set
 291            {
 1292                CommunicationObject.ThrowIfDisposedOrImmutable();
 1293                if (value != null)
 294                {
 1295                    _knownTypes = new Collection<Type>(value);
 296                }
 297                else
 298                {
 0299                    _knownTypes = null;
 300                }
 0301            }
 302        }
 303
 304        public int MaxMessageSize
 305        {
 0306            get => _maxMessageSize;
 307            set
 308            {
 1309                CommunicationObject.ThrowIfDisposedOrImmutable();
 1310                _maxMessageSize = value;
 1311            }
 312        }
 313
 1314        protected string SecurityContextTokenUri { get; private set; }
 315
 1316        private object ThisLock => CommunicationObject;
 317
 318        // helpers
 319        protected SecurityContextSecurityToken IssueSecurityContextToken(UniqueId contextId, string id, byte[] key,
 320            DateTime tokenEffectiveTime, DateTime tokenExpirationTime,
 0321            ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, bool isCookieMode) => IssueSecurityContextTo
 0322                tokenEffectiveTime, tokenExpirationTime, authorizationPolicies, isCookieMode);
 323
 324        protected SecurityContextSecurityToken IssueSecurityContextToken(UniqueId contextId, string id, byte[] key,
 325            DateTime tokenEffectiveTime, DateTime tokenExpirationTime, UniqueId keyGeneration, DateTime keyEffectiveTime
 326            DateTime keyExpirationTime, ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, bool isCookieMod
 327        {
 328            //  this.CommunicationObject.ThrowIfClosedOrNotOpen();
 0329            if (_securityStateEncoder == null && isCookieMode)
 330            {
 0331                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Sct
 332            }
 0333            byte[] cookieBlob = (isCookieMode) ? _cookieSerializer.CreateCookieFromSecurityContext(contextId, id, key, t
 0334                                keyEffectiveTime, keyExpirationTime, authorizationPolicies) : null;
 335
 0336            SecurityContextSecurityToken issuedToken = new SecurityContextSecurityToken(contextId, id, key, tokenEffecti
 0337                authorizationPolicies, isCookieMode, cookieBlob, keyGeneration, keyEffectiveTime, keyExpirationTime);
 0338            return issuedToken;
 339        }
 340
 341        private void InitializeDefaults()
 342        {
 1343            _encryptStateInServiceToken = !DefaultServerMaintainState;
 1344            _serviceTokenLifetime = DefaultServerIssuedTokenLifetime;
 1345            _maximumCachedNegotiationState = DefaultServerMaxActiveNegotiations;
 1346            _negotiationTimeout = s_defaultServerMaxNegotiationLifetime;
 1347            _isClientAnonymous = false;
 1348            _standardsManager = s_defaultStandardsManager;
 1349            _securityStateEncoder = s_defaultSecurityStateEncoder;
 1350            _maximumConcurrentNegotiations = DefaultServerMaxActiveNegotiations;
 351            // we rely on the transport encoders to enforce the message size except in the
 352            // mixed mode nego case, where the client is unauthenticated and the maxMessageSize is too
 353            // large to be a mitigation
 1354            _maxMessageSize = int.MaxValue;
 1355        }
 356
 357        public override Task CloseAsync(CancellationToken token)
 358        {
 0359            if (_negotiationHost != null)
 360            {
 0361                _negotiationHost = null;
 362            }
 363
 0364            lock (ThisLock)
 365            {
 0366                if (_idlingNegotiationSessionTimer != null && !_isTimerCancelled)
 367                {
 0368                    _isTimerCancelled = true;
 0369                    _idlingNegotiationSessionTimer.Cancel();
 370                }
 0371            }
 0372            return base.CloseAsync(token); ;
 373        }
 374
 375        public override void OnAbort()
 376        {
 0377            if (_negotiationHost != null)
 378            {
 379                // this.negotiationHost.Abort();
 0380                _negotiationHost = null;
 381            }
 382
 0383            lock (ThisLock)
 384            {
 0385                if (_idlingNegotiationSessionTimer != null && !_isTimerCancelled)
 386                {
 0387                    _isTimerCancelled = true;
 0388                    _idlingNegotiationSessionTimer.Cancel();
 389                }
 0390            }
 0391            base.OnAbort();
 0392        }
 393
 394        public override Task OpenAsync(CancellationToken token)
 395        {
 1396            if (IssuerBindingContext == null)
 397            {
 0398                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Iss
 399            }
 1400            if (IssuedSecurityTokenParameters == null)
 401            {
 0402                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Iss
 403            }
 1404            if (SecurityAlgorithmSuite == null)
 405            {
 0406                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Sec
 407            }
 1408            if (IssuedTokenCache == null)
 409            {
 0410                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Iss
 411            }
 1412            SetupServiceHost();
 1413            if (_negotiationHost != null)
 414            {
 1415                _negotiationHost.InitializeRuntime();
 416            }
 417
 1418            _stateCache = new NegotiationTokenAuthenticatorStateCache<T>(NegotiationTimeout, MaximumCachedNegotiationSta
 1419            SecurityContextTokenUri = StandardsManager.SecureConversationDriver.TokenTypeUri;
 1420            if (SecurityStateEncoder != null)
 421            {
 1422                _cookieSerializer = new SecurityContextCookieSerializer(SecurityStateEncoder, KnownTypes);
 423            }
 1424            if (_negotiationTimeout < TimeSpan.MaxValue)
 425            {
 1426                lock (ThisLock)
 427                {
 1428                    _activeNegotiationChannels1 = new List<IChannel>();
 1429                    _activeNegotiationChannels2 = new List<IChannel>();
 1430                    _idlingNegotiationSessionTimer = new IOThreadTimer(new Action<object>(OnIdlingNegotiationSessionTime
 1431                    _isTimerCancelled = false;
 1432                    _idlingNegotiationSessionTimer.Set(_negotiationTimeout);
 1433                }
 434            }
 1435            return base.OpenAsync();
 436        }
 437
 0438        protected override bool CanValidateTokenCore(SecurityToken token) => (token is SecurityContextSecurityToken);
 439
 440        protected override ValueTask<ReadOnlyCollection<IAuthorizationPolicy>> ValidateTokenCoreAsync(SecurityToken toke
 441        {
 0442            SecurityContextSecurityToken sct = (SecurityContextSecurityToken)token;
 0443            return new ValueTask<ReadOnlyCollection<IAuthorizationPolicy>>(sct.AuthorizationPolicies);
 444        }
 445
 446        protected abstract Binding GetNegotiationBinding(Binding binding);
 447        protected abstract bool IsMultiLegNegotiation { get; }
 448
 2449        internal static TimeSpan DefaultServerIssuedTokenLifetime { get; } = TimeSpan.Parse(DefaultServerIssuedTokenLife
 450
 451        protected abstract MessageFilter GetListenerFilter();
 452
 453        private void SetupServiceHost()
 454        {
 455            //   ChannelBuilder channelBuilder = new ChannelBuilder(this.IssuerBindingContext.Clone(), true);
 456            //   channelBuilder.Binding.Elements.Insert(0, new ReplyAdapterBindingElement());
 457            // channelBuilder.Binding = new CustomBinding(this.GetNegotiationBinding(channelBuilder.Binding));
 1458            ChannelBuilder channelBuilder = IssuerBindingContext.BindingParameters.Find<ChannelBuilder>();
 1459            _negotiationHost = new NegotiationHost(this, ListenUri, channelBuilder, GetListenerFilter());
 1460        }
 461
 462
 463        // message processing abstract method
 464        protected abstract ValueTask<(BodyWriter, T)> ProcessRequestSecurityTokenAsync(Message request, RequestSecurityT
 465        protected abstract ValueTask<BodyWriter> ProcessRequestSecurityTokenResponseAsync(T negotiationState, Message re
 466
 467        // message handlers
 468        protected virtual void ParseMessageBody(Message message, out string context, out RequestSecurityToken requestSec
 469        {
 0470            requestSecurityToken = null;
 0471            requestSecurityTokenResponse = null;
 0472            if (message.Headers.Action == RequestSecurityTokenAction.Value)
 473            {
 0474                XmlDictionaryReader reader = message.GetReaderAtBodyContents();
 0475                using (reader)
 476                {
 0477                    requestSecurityToken = RequestSecurityToken.CreateFrom(StandardsManager, reader);
 0478                    message.ReadFromBodyContentsToEnd(reader);
 0479                }
 0480                context = requestSecurityToken.Context;
 481            }
 0482            else if (message.Headers.Action == RequestSecurityTokenResponseAction.Value)
 483            {
 0484                XmlDictionaryReader reader = message.GetReaderAtBodyContents();
 0485                using (reader)
 486                {
 0487                    requestSecurityTokenResponse = RequestSecurityTokenResponse.CreateFrom(StandardsManager, reader);
 0488                    message.ReadFromBodyContentsToEnd(reader);
 0489                }
 0490                context = requestSecurityTokenResponse.Context;
 491            }
 492            else
 493            {
 0494                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.Format(SR.InvalidActionForNegoti
 495            }
 496        }
 497
 498        private static Message CreateReply(Message request, XmlDictionaryString action, BodyWriter body)
 499        {
 0500            if (request.Headers.MessageId != null)
 501            {
 0502                Message reply = Message.CreateMessage(request.Version, ActionHeader.Create(action, request.Version.Addre
 0503                reply.InitializeReply(request);
 0504                return reply;
 505            }
 506            else
 507            {
 508                // the message id may not be present if MapToHttp is true
 0509                return Message.CreateMessage(request.Version, ActionHeader.Create(action, request.Version.Addressing), b
 510            }
 511        }
 512
 513        private void OnTokenIssued(SecurityToken token)
 514        {
 0515            IssuedSecurityTokenHandler?.Invoke(token, null);
 0516        }
 517
 518        private void AddNegotiationChannelForIdleTracking()
 519        {
 0520            if (OperationContext.Current.SessionId == null)
 521            {
 0522                return;
 523            }
 0524            lock (ThisLock)
 525            {
 0526                if (_idlingNegotiationSessionTimer == null)
 527                {
 0528                    return;
 529                }
 0530                IChannel channel = OperationContext.Current.Channel;
 0531                if (!_activeNegotiationChannels1.Contains(channel) && !_activeNegotiationChannels2.Contains(channel))
 532                {
 0533                    _activeNegotiationChannels1.Add(channel);
 534                }
 0535                if (_isTimerCancelled)
 536                {
 0537                    _isTimerCancelled = false;
 0538                    _idlingNegotiationSessionTimer.Set(_negotiationTimeout);
 539                }
 0540            }
 0541        }
 542
 543        private void RemoveNegotiationChannelFromIdleTracking()
 544        {
 0545            if (OperationContext.Current.SessionId == null)
 546            {
 0547                return;
 548            }
 0549            lock (ThisLock)
 550            {
 0551                if (_idlingNegotiationSessionTimer == null)
 552                {
 0553                    return;
 554                }
 0555                IChannel channel = OperationContext.Current.Channel;
 0556                _activeNegotiationChannels1.Remove(channel);
 0557                _activeNegotiationChannels2.Remove(channel);
 0558                if (_activeNegotiationChannels1.Count == 0 && _activeNegotiationChannels2.Count == 0)
 559                {
 0560                    _isTimerCancelled = true;
 0561                    _idlingNegotiationSessionTimer.Cancel();
 562                }
 0563            }
 0564        }
 565
 566        private void OnIdlingNegotiationSessionTimer(object state)
 567        {
 0568            lock (ThisLock)
 569            {
 0570                if (_isTimerCancelled || (CommunicationObject.State != CommunicationState.Opened && CommunicationObject.
 571                {
 0572                    return;
 573                }
 574
 575                try
 576                {
 0577                    for (int i = 0; i < _activeNegotiationChannels2.Count; ++i)
 578                    {
 0579                        _activeNegotiationChannels2[i].Abort();
 580                    }
 0581                    List<IChannel> temp = _activeNegotiationChannels2;
 0582                    temp.Clear();
 0583                    _activeNegotiationChannels2 = _activeNegotiationChannels1;
 0584                    _activeNegotiationChannels1 = temp;
 0585                }
 586                catch (Exception e)
 587                {
 0588                    if (Fx.IsFatal(e))
 589                    {
 0590                        throw;
 591                    }
 0592                }
 593                finally
 594                {
 0595                    if (CommunicationObject.State == CommunicationState.Opened || CommunicationObject.State == Communica
 596                    {
 0597                        if (_activeNegotiationChannels1.Count == 0 && _activeNegotiationChannels2.Count == 0)
 598                        {
 0599                            _isTimerCancelled = true;
 0600                            _idlingNegotiationSessionTimer.Cancel();
 601                        }
 602                        else
 603                        {
 0604                            _idlingNegotiationSessionTimer.Set(_negotiationTimeout);
 605                        }
 606                    }
 0607                }
 608            }
 0609        }
 610
 611        private async ValueTask<Message> ProcessRequestCoreAsync(Message request)
 612        {
 0613            if (request == null)
 614            {
 0615                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(request));
 616            }
 617
 0618            bool disposeRequest = false;
 0619            bool isNegotiationFailure = true;
 0620            T negotiationState = null;
 621
 622            try
 623            {
 624                // validate the message size if needed
 0625                if (_maxMessageSize < int.MaxValue)
 626                {
 0627                    string action = request.Headers.Action;
 628                    try
 629                    {
 0630                        using (MessageBuffer buffer = request.CreateBufferedCopy(_maxMessageSize))
 631                        {
 0632                            request = buffer.CreateMessage();
 0633                            disposeRequest = true;
 0634                        }
 0635                    }
 0636                    catch (QuotaExceededException e)
 637                    {
 0638                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.Fo
 639                    }
 640                }
 641                try
 642                {
 0643                    Uri to = request.Headers.To;
 0644                    ParseMessageBody(request, out string context, out RequestSecurityToken rst, out RequestSecurityToken
 645                    // check if there is existing state
 0646                    if (context != null)
 647                    {
 0648                        negotiationState = _stateCache.GetState(context);
 649                    }
 650                    else
 651                    {
 0652                        negotiationState = null;
 653                    }
 0654                    bool disposeState = false;
 655                    BodyWriter replyBody;
 656                    try
 657                    {
 0658                        if (rst != null)
 659                        {
 0660                            if (negotiationState != null)
 661                            {
 0662                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationExcep
 663                            }
 0664                            (BodyWriter replyBody, T negotiatonState) processedRequestSecurityToken = await ProcessReque
 0665                            negotiationState = processedRequestSecurityToken.negotiatonState;
 0666                            replyBody = processedRequestSecurityToken.replyBody;
 0667                            await using (await negotiationState.AsyncLock.TakeLockAsync())
 668                            {
 0669                                if (negotiationState.IsNegotiationCompleted)
 670                                {
 671                                    // if session-sct add it to cache and add a redirect header
 0672                                    if (!negotiationState.ServiceToken.IsCookieMode)
 673                                    {
 0674                                        IssuedTokenCache.AddContext(negotiationState.ServiceToken);
 675                                    }
 676
 0677                                    OnTokenIssued(negotiationState.ServiceToken);
 678                                    // SecurityTraceRecordHelper.TraceServiceSecurityNegotiationCompleted(request, this,
 0679                                    disposeState = true;
 680                                }
 681                                else
 682                                {
 0683                                    _stateCache.AddState(context, negotiationState);
 0684                                    disposeState = false;
 685                                }
 686
 0687                                AddNegotiationChannelForIdleTracking();
 688                            }
 689                        }
 690                        else
 691                        {
 0692                            if (negotiationState == null)
 693                            {
 0694                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationExcep
 695                            }
 696
 0697                            await using (await negotiationState.AsyncLock.TakeLockAsync())
 698                            {
 0699                                replyBody = await ProcessRequestSecurityTokenResponseAsync(negotiationState, request,
 0700                                    rstr); //.AsTask().GetAwaiter().GetResult();
 0701                                if (negotiationState.IsNegotiationCompleted)
 702                                {
 703                                    // if session-sct add it to cache and add a redirect header
 0704                                    if (!negotiationState.ServiceToken.IsCookieMode)
 705                                    {
 0706                                        IssuedTokenCache.AddContext(negotiationState.ServiceToken);
 707                                    }
 708
 0709                                    OnTokenIssued(negotiationState.ServiceToken);
 710                                    // SecurityTraceRecordHelper.TraceServiceSecurityNegotiationCompleted(request, this,
 0711                                    disposeState = true;
 712                                }
 713                                else
 714                                {
 0715                                    disposeState = false;
 716                                }
 717                            }
 718                        }
 719
 0720                        if (negotiationState.IsNegotiationCompleted && null != ListenUri)
 721                        {
 722                            //if (AuditLevel.Success == (this.messageAuthenticationAuditLevel & AuditLevel.Success))
 723                            //{
 724                            //    string primaryIdentity = negotiationState.GetRemoteIdentityName();
 725                            //    SecurityAuditHelper.WriteSecurityNegotiationSuccessEvent(this.auditLogLocation,
 726                            //        this.suppressAuditFailure, request, request.Headers.To, request.Headers.Action,
 727                            //        primaryIdentity, this.GetType().Name);
 728                            //}
 729                        }
 0730                        isNegotiationFailure = false;
 0731                    }
 732                    catch (Exception exception)
 733                    {
 0734                        if (Fx.IsFatal(exception))
 735                        {
 0736                            throw;
 737                        }
 738
 739                        //                        if (PerformanceCounters.PerformanceCountersEnabled && null != this.Lis
 740                        //                        {
 741                        //                            PerformanceCounters.AuthenticationFailed(request, this.ListenUri);
 742                        //                        }
 743                        //                        if (AuditLevel.Failure == (this.messageAuthenticationAuditLevel & Audi
 744                        //                        {
 745                        //                            try
 746                        //                            {
 747                        //                                string primaryIdentity = (negotiationState != null) ? negotiat
 748                        //                                SecurityAuditHelper.WriteSecurityNegotiationFailureEvent(this.
 749                        //                                    this.suppressAuditFailure, request, request.Headers.To, re
 750                        //                                    primaryIdentity, this.GetType().Name, exception);
 751                        //                            }
 752                        //#pragma warning suppress 56500
 753                        //                            catch (Exception auditException)
 754                        //                            {
 755                        //                                if (Fx.IsFatal(auditException))
 756                        //                                    throw;
 757
 758                        //                                DiagnosticUtility.TraceHandledException(auditException, TraceE
 759                        //                            }
 760                        //                        }
 761
 0762                        disposeState = true;
 0763                        throw;
 764                    }
 765                    finally
 766                    {
 0767                        if (disposeState)
 768                        {
 0769                            if (negotiationState != null)
 770                            {
 0771                                if (context != null)
 772                                {
 0773                                    _stateCache.RemoveState(context);
 774                                }
 0775                                negotiationState.Dispose();
 776                            }
 777                        }
 778                    }
 779
 0780                    return CreateReply(request, (replyBody is RequestSecurityTokenResponseCollection) ? RequestSecurityT
 781                }
 782                finally
 783                {
 0784                    if (disposeRequest)
 785                    {
 0786                        request.Close();
 787                    }
 788                }
 789            }
 790            finally
 791            {
 0792                if (isNegotiationFailure)
 793                {
 0794                    AddNegotiationChannelForIdleTracking();
 795                }
 0796                else if (negotiationState != null && negotiationState.IsNegotiationCompleted)
 797                {
 0798                    RemoveNegotiationChannelFromIdleTracking();
 799                }
 800            }
 0801        }
 802
 803        // negotiation failure methods
 804        private Message HandleNegotiationException(Message request, Exception e) =>
 805
 806            //SecurityTraceRecordHelper.TraceServiceSecurityNegotiationFailure<T>(
 807            //                        EventTraceActivityHelper.TryExtractActivity(request),
 808            //                        this,
 809            //                        e);
 0810            CreateFault(request, e);
 811
 812        private Message CreateFault(Message request, Exception e)
 813        {
 0814            MessageVersion version = request.Version;
 815            FaultCode subCode;
 816            FaultReason reason;
 817            bool isSenderFault;
 0818            if (e is SecurityTokenValidationException || e is System.ComponentModel.Win32Exception)
 819            {
 0820                subCode = new FaultCode(TrustApr2004Strings.FailedAuthenticationFaultCode, TrustFeb2005Strings.Namespace
 0821                reason = new FaultReason(SR.Format(SR.FailedAuthenticationTrustFaultCode), CultureInfo.CurrentCulture);
 0822                isSenderFault = true;
 823            }
 0824            else if (e is QuotaExceededException)
 825            {
 826                // send a receiver fault so that the sender can retry
 0827                subCode = new FaultCode(DotNetSecurityStrings.SecurityServerTooBusyFault, DotNetSecurityStrings.Namespac
 0828                reason = new FaultReason(SR.Format(SR.NegotiationQuotasExceededFaultReason), CultureInfo.CurrentCulture)
 0829                isSenderFault = false;
 830            }
 831            else
 832            {
 0833                subCode = new FaultCode(TrustApr2004Strings.InvalidRequestFaultCode, TrustFeb2005Strings.Namespace);
 0834                reason = new FaultReason(SR.Format(SR.InvalidRequestTrustFaultCode), CultureInfo.CurrentCulture);
 0835                isSenderFault = true;
 836            }
 837            FaultCode faultCode;
 0838            if (isSenderFault)
 839            {
 0840                faultCode = FaultCode.CreateSenderFaultCode(subCode);
 841            }
 842            else
 843            {
 0844                faultCode = FaultCode.CreateReceiverFaultCode(subCode);
 845            }
 0846            MessageFault fault = MessageFault.CreateFault(faultCode, reason);
 0847            Message faultReply = Message.CreateMessage(version, fault, version.Addressing.DefaultFaultAction);
 0848            faultReply.Headers.RelatesTo = request.Headers.MessageId;
 849
 0850            return faultReply;
 851        }
 852
 853        private class NegotiationHost //: ServiceHostBase
 854        {
 855            private readonly NegotiationTokenAuthenticator<T> _authenticator;
 856            private readonly Uri _listenUri;
 857            private readonly ChannelBuilder _channelBuilder;
 858            private readonly MessageFilter _listenerFilter;
 859
 1860            public NegotiationHost(NegotiationTokenAuthenticator<T> authenticator, Uri listenUri, ChannelBuilder channel
 861            {
 1862                _authenticator = authenticator;
 1863                _listenUri = listenUri;
 1864                _channelBuilder = channelBuilder;
 1865                _listenerFilter = listenerFilter;
 1866            }
 867
 868            //protected override ServiceDescription CreateDescription(out IDictionary<string, ContractDescription> imple
 869            //{
 870            //    implementedContracts = null;
 871            //    return null;
 872            //}
 873
 874            internal void InitializeRuntime()
 875            {
 876
 1877                MessageFilter contractFilter = _listenerFilter;
 1878                int filterPriority = int.MaxValue - 20;
 1879                List<Type> endpointChannelTypes = new List<Type> {  typeof(IReplyChannel),
 1880                                                           typeof(IDuplexChannel),
 1881                                                           typeof(IReplySessionChannel),
 1882                                                           typeof(IDuplexSessionChannel) };
 1883                Binding binding = _authenticator.IssuerBindingContext.Binding;
 1884                var bindingQname = new XmlQualifiedName(binding.Name, binding.Namespace);
 1885                var channelDispatcher = new ChannelDispatcher(_listenUri, binding, bindingQname.ToString(), binding, end
 1886                {
 1887                    MessageVersion = binding.MessageVersion,
 1888                    ManualAddressing = true
 1889                };
 890                //TODO : Throttle
 891                // channelDispatcher.ServiceThrottle = new ServiceThrottle(this);
 892                // channelDispatcher.ServiceThrottle.MaxConcurrentCalls = this.authenticator.MaximumConcurrentNegotiatio
 893                // channelDispatcher.ServiceThrottle.MaxConcurrentSessions = this.authenticator.MaximumConcurrentNegotia
 1894                EndpointDispatcher endpointDispatcher = new EndpointDispatcher(new EndpointAddress(_listenUri, new Addre
 1895                {
 1896                    DispatchRuntime = {
 1897                    SingletonInstanceContext = new InstanceContext( null,  _authenticator, false),
 1898                    ConcurrencyMode = ConcurrencyMode.Multiple
 1899                    },
 1900                    AddressFilter = new MatchAllMessageFilter(),
 1901                    ContractFilter = _listenerFilter,
 1902                    FilterPriority = filterPriority
 1903                };
 1904                endpointDispatcher.DispatchRuntime.PrincipalPermissionMode = PrincipalPermissionMode.None;
 1905                endpointDispatcher.DispatchRuntime.InstanceContextProvider = new SingletonInstanceContextProvider(endpoi
 1906                endpointDispatcher.DispatchRuntime.SynchronizationContext = null;
 1907                endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = new DispatchOperation(endpointDispatcher
 1908                {
 1909                    Formatter = new MessageOperationFormatter(),
 1910                    Invoker = new NegotiationTokenAuthenticator<T>.NegotiationHost.NegotiationSyncInvoker(_authenticator
 1911                };
 1912                channelDispatcher.Endpoints.Add(endpointDispatcher);
 1913                channelDispatcher.Init();
 1914                Task openTask = channelDispatcher.OpenAsync();
 915                Fx.Assert(openTask.IsCompleted, "ChannelDispatcher should open synchronously");
 1916                openTask.GetAwaiter().GetResult();
 1917                ServiceDispatcher service = new ServiceDispatcher(channelDispatcher);
 1918                _channelBuilder.AddServiceDispatcher<IReplyChannel>(service, new ChannelDemuxerFilter(contractFilter, fi
 1919            }
 920
 921            private class NegotiationSyncInvoker : IOperationInvoker
 922            {
 923                private readonly NegotiationTokenAuthenticator<T> _parent;
 924
 2925                internal NegotiationSyncInvoker(NegotiationTokenAuthenticator<T> parent) => _parent = parent;
 926
 0927                public bool IsSynchronous => true;
 928
 0929                public object[] AllocateInputs() => EmptyArray<object>.Allocate(1);
 930
 931                public async ValueTask<(object returnValue, object[] outputs)> InvokeAsync(object instance, object[] inp
 932                {
 0933                    object[] outputs = EmptyArray<object>.Allocate(0);
 0934                    if (!(inputs[0] is Message message))
 935                    {
 0936                        return ((object)null, outputs);
 937                    }
 0938                    object returnVal = await _parent.ProcessRequestCoreAsync(message);
 0939                    return (returnVal, outputs);
 0940                }
 941            }
 942        }
 943    }
 944}

Methods/Properties

.cctor()
.ctor()
IssuedSecurityTokenHandler()
RenewedSecurityTokenHandler()
EncryptStateInServiceToken()
EncryptStateInServiceToken(System.Boolean)
ServiceTokenLifetime()
ServiceTokenLifetime(System.TimeSpan)
MaximumCachedNegotiationState()
MaximumCachedNegotiationState(System.Int32)
MaximumConcurrentNegotiations()
MaximumConcurrentNegotiations(System.Int32)
NegotiationTimeout()
NegotiationTimeout(System.TimeSpan)
IsClientAnonymous()
IsClientAnonymous(System.Boolean)
SecurityAlgorithmSuite()
SecurityAlgorithmSuite(CoreWCF.Security.SecurityAlgorithmSuite)
EndpointFilterTable()
EndpointFilterTable(CoreWCF.Dispatcher.IMessageFilterTable`1<CoreWCF.EndpointAddress>)
WCF.Security.Tokens.ISecurityContextSecurityTokenCacheProvider.get_TokenCache()
RequestSecurityTokenAction()
RequestSecurityTokenResponseAction()
RequestSecurityTokenResponseFinalAction()
StandardsManager()
StandardsManager(CoreWCF.Security.SecurityStandardsManager)
IssuedSecurityTokenParameters()
IssuedSecurityTokenParameters(CoreWCF.Security.Tokens.SecurityTokenParameters)
IssuedTokenCache()
IssuedTokenCache(CoreWCF.Security.Tokens.ISecurityContextSecurityTokenCache)
SuppressAuditFailure()
SuppressAuditFailure(System.Boolean)
IssuerBindingContext()
IssuerBindingContext(CoreWCF.Channels.BindingContext)
ListenUri()
ListenUri(System.Uri)
SecurityStateEncoder()
SecurityStateEncoder(CoreWCF.Security.SecurityStateEncoder)
KnownTypes()
KnownTypes(System.Collections.Generic.IList`1<System.Type>)
MaxMessageSize()
MaxMessageSize(System.Int32)
SecurityContextTokenUri()
ThisLock()
IssueSecurityContextToken(System.Xml.UniqueId,System.String,System.Byte[],System.DateTime,System.DateTime,System.Collections.ObjectModel.ReadOnlyCollection`1<CoreWCF.IdentityModel.Policy.IAuthorizationPolicy>,System.Boolean)
IssueSecurityContextToken(System.Xml.UniqueId,System.String,System.Byte[],System.DateTime,System.DateTime,System.Xml.UniqueId,System.DateTime,System.DateTime,System.Collections.ObjectModel.ReadOnlyCollection`1<CoreWCF.IdentityModel.Policy.IAuthorizationPolicy>,System.Boolean)
InitializeDefaults()
CloseAsync(System.Threading.CancellationToken)
OnAbort()
OpenAsync(System.Threading.CancellationToken)
CanValidateTokenCore(CoreWCF.IdentityModel.Tokens.SecurityToken)
ValidateTokenCoreAsync(CoreWCF.IdentityModel.Tokens.SecurityToken)
DefaultServerIssuedTokenLifetime()
SetupServiceHost()
ParseMessageBody(CoreWCF.Channels.Message,System.String&,CoreWCF.Security.RequestSecurityToken&,CoreWCF.Security.RequestSecurityTokenResponse&)
CreateReply(CoreWCF.Channels.Message,System.Xml.XmlDictionaryString,CoreWCF.Channels.BodyWriter)
OnTokenIssued(CoreWCF.IdentityModel.Tokens.SecurityToken)
AddNegotiationChannelForIdleTracking()
RemoveNegotiationChannelFromIdleTracking()
OnIdlingNegotiationSessionTimer(System.Object)
ProcessRequestCoreAsync()
HandleNegotiationException(CoreWCF.Channels.Message,System.Exception)
CreateFault(CoreWCF.Channels.Message,System.Exception)
.ctor(CoreWCF.Security.NegotiationTokenAuthenticator`1<T>,System.Uri,CoreWCF.Channels.ChannelBuilder,CoreWCF.Dispatcher.MessageFilter)
InitializeRuntime()
.ctor(CoreWCF.Security.NegotiationTokenAuthenticator`1<T>)
IsSynchronous()
AllocateInputs()
InvokeAsync()