| File: System\ServiceModel\Security\TransportSecurityProtocol.cs | Web Access |
| Project: src\src\System.ServiceModel.Primitives\src\System.ServiceModel.Primitives.csproj (System.ServiceModel.Primitives) |
// 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.Collections.Generic; using System.Collections.ObjectModel; using System.IdentityModel.Policy; using System.IdentityModel.Tokens; using System.Runtime; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.Threading.Tasks; namespace System.ServiceModel.Security { internal class TransportSecurityProtocol : SecurityProtocol { public TransportSecurityProtocol(TransportSecurityProtocolFactory factory, EndpointAddress target, Uri via) : base(factory, target, via) { } public override async Task<Message> SecureOutgoingMessageAsync(Message message, TimeSpan timeout) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(message)); } CommunicationObject.ThrowIfClosedOrNotOpen(); string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor; try { if (SecurityProtocolFactory.ActAsInitiator) { message = await SecureOutgoingMessageAtInitiatorAsync(message, actor, timeout); } else { throw ExceptionHelper.PlatformNotSupported(); } base.OnOutgoingMessageSecured(message); } catch { base.OnSecureOutgoingMessageFailure(message); throw; } return message; } protected virtual async Task<Message> SecureOutgoingMessageAtInitiatorAsync(Message message, string actor, TimeSpan timeout) { IList<SupportingTokenSpecification> supportingTokens = await TryGetSupportingTokensAsync(SecurityProtocolFactory, Target, Via, message, timeout); SetUpDelayedSecurityExecution(ref message, actor, supportingTokens); return message; } internal void SetUpDelayedSecurityExecution(ref Message message, string actor, IList<SupportingTokenSpecification> supportingTokens) { SendSecurityHeader securityHeader = CreateSendSecurityHeaderForTransportProtocol(message, actor, SecurityProtocolFactory); AddSupportingTokens(securityHeader, supportingTokens); message = securityHeader.SetupExecution(); } public sealed override void VerifyIncomingMessage(ref Message message, TimeSpan timeout) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(message)); } CommunicationObject.ThrowIfClosedOrNotOpen(); try { VerifyIncomingMessageCore(ref message, timeout); } catch (MessageSecurityException e) { base.OnVerifyIncomingMessageFailure(message, e); throw; } catch (Exception e) { // Always immediately rethrow fatal exceptions. if (Fx.IsFatal(e)) { throw; } base.OnVerifyIncomingMessageFailure(message, e); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SRP.MessageSecurityVerificationFailed, e)); } } protected void AttachRecipientSecurityProperty(Message message, IList<SecurityToken> basicTokens, IList<SecurityToken> endorsingTokens, IList<SecurityToken> signedEndorsingTokens, IList<SecurityToken> signedTokens, Dictionary<SecurityToken, ReadOnlyCollection<IAuthorizationPolicy>> tokenPoliciesMapping) { SecurityMessageProperty security = SecurityMessageProperty.GetOrCreate(message); AddSupportingTokenSpecification(security, basicTokens, endorsingTokens, signedEndorsingTokens, signedTokens, tokenPoliciesMapping); security.ServiceSecurityContext = new ServiceSecurityContext(security.GetInitiatorTokenAuthorizationPolicies()); } protected virtual void VerifyIncomingMessageCore(ref Message message, TimeSpan timeout) { TransportSecurityProtocolFactory factory = (TransportSecurityProtocolFactory)SecurityProtocolFactory; string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor; ReceiveSecurityHeader securityHeader = factory.StandardsManager.TryCreateReceiveSecurityHeader(message, actor, factory.IncomingAlgorithmSuite, (factory.ActAsInitiator) ? MessageDirection.Output : MessageDirection.Input); bool expectBasicTokens; bool expectEndorsingTokens; bool expectSignedTokens; IList<SupportingTokenAuthenticatorSpecification> supportingAuthenticators = factory.GetSupportingTokenAuthenticators(message.Headers.Action, out expectSignedTokens, out expectBasicTokens, out expectEndorsingTokens); if (securityHeader == null) { bool expectSupportingTokens = expectEndorsingTokens || expectSignedTokens || expectBasicTokens; if ((factory.ActAsInitiator && (!factory.AddTimestamp || factory.SecurityBindingElement.EnableUnsecuredResponse)) || (!factory.ActAsInitiator && !factory.AddTimestamp && !expectSupportingTokens)) { return; } else { if (String.IsNullOrEmpty(actor)) { throw System.ServiceModel.Diagnostics.TraceUtility.ThrowHelperError(new MessageSecurityException( SRP.UnableToFindSecurityHeaderInMessageNoActor), message); } else { throw System.ServiceModel.Diagnostics.TraceUtility.ThrowHelperError(new MessageSecurityException( SRP.Format(SRP.UnableToFindSecurityHeaderInMessage, actor)), message); } } } securityHeader.RequireMessageProtection = false; securityHeader.ExpectBasicTokens = expectBasicTokens; securityHeader.ExpectSignedTokens = expectSignedTokens; securityHeader.ExpectEndorsingTokens = expectEndorsingTokens; securityHeader.MaxReceivedMessageSize = factory.SecurityBindingElement.MaxReceivedMessageSize; securityHeader.ReaderQuotas = factory.SecurityBindingElement.ReaderQuotas; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); if (!factory.ActAsInitiator) { throw ExceptionHelper.PlatformNotSupported(); } securityHeader.ReplayDetectionEnabled = factory.DetectReplays; securityHeader.SetTimeParameters(factory.NonceCache, factory.ReplayWindow, factory.MaxClockSkew); securityHeader.Process(timeoutHelper.RemainingTime(), SecurityUtils.GetChannelBindingFromMessage(message), factory.ExtendedProtectionPolicy); message = securityHeader.ProcessedMessage; if (!factory.ActAsInitiator) { AttachRecipientSecurityProperty(message, securityHeader.BasicSupportingTokens, securityHeader.EndorsingSupportingTokens, securityHeader.SignedEndorsingSupportingTokens, securityHeader.SignedSupportingTokens, securityHeader.SecurityTokenAuthorizationPoliciesMapping); } base.OnIncomingMessageVerified(message); } } }