private async Task <SecurityToken> DoOperationAsync(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout) { if (target == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(target)); } if (operation == SecuritySessionOperation.Renew && currentToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(currentToken)); } IAsyncRequestChannel channel = null; try { channel = CreateChannel(operation, target, via); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); await channel.OpenAsync(timeoutHelper.RemainingTime()); object requestState; GenericXmlSecurityToken issuedToken; using (Message requestMessage = CreateRequest(operation, target, currentToken, out requestState)) { EventTraceActivity eventTraceActivity = null; TraceUtility.ProcessOutgoingMessage(requestMessage, eventTraceActivity); using (Message reply = await channel.RequestAsync(requestMessage, timeoutHelper.RemainingTime())) { if (reply == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.FailToRecieveReplyFromNegotiation)); } TraceUtility.ProcessIncomingMessage(reply, eventTraceActivity); ThrowIfFault(reply, _targetAddress); issuedToken = ProcessReply(reply, operation, requestState); ValidateKeySize(issuedToken); } } await channel.CloseAsync(timeoutHelper.RemainingTime()); OnOperationSuccess(operation, target, issuedToken, currentToken); return(issuedToken); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (e is TimeoutException) { e = new TimeoutException(SR.Format(SR.ClientSecuritySessionRequestTimeout, timeout), e); } OnOperationFailure(operation, target, currentToken, e, channel); throw; } }
/* * Negotiation consists of the following steps (some may be async in the async case): * 1. Create negotiation state * 2. Initialize channel factories * 3. Create an channel * 4. Open the channel * 5. Create the next message to send to server * 6. Send the message and get reply * 8. Process incoming message and get next outgoing message. * 9. If no outgoing message, then negotiation is over. Go to step 11. * 10. Goto step 6 * 11. Close the IAsyncRequest channel and complete */ protected async Task <SecurityToken> DoNegotiationAsync(TimeSpan timeout) { ThrowIfClosedOrCreated(); TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); IAsyncRequestChannel rstChannel = null; T negotiationState = null; TimeSpan timeLeft = timeout; int legs = 1; try { negotiationState = await CreateNegotiationStateAsync(_targetAddress, _via, timeoutHelper.RemainingTime()); InitializeNegotiationState(negotiationState); await InitializeChannelFactoriesAsync(negotiationState.RemoteAddress, timeoutHelper.RemainingTime()); rstChannel = CreateClientChannel(negotiationState.RemoteAddress, _via); await rstChannel.OpenAsync(timeoutHelper.RemainingTime()); Message nextOutgoingMessage = null; Message incomingMessage = null; SecurityToken serviceToken = null; for (; ;) { nextOutgoingMessage = GetNextOutgoingMessage(incomingMessage, negotiationState); if (incomingMessage != null) { incomingMessage.Close(); } if (nextOutgoingMessage != null) { using (nextOutgoingMessage) { timeLeft = timeoutHelper.RemainingTime(); incomingMessage = await rstChannel.RequestAsync(nextOutgoingMessage, timeLeft); if (incomingMessage == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.FailToRecieveReplyFromNegotiation)); } } legs += 2; } else { if (!negotiationState.IsNegotiationCompleted) { throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.NoNegotiationMessageToSend), incomingMessage); } try { rstChannel.Close(timeoutHelper.RemainingTime()); } catch (CommunicationException) { rstChannel.Abort(); } catch (TimeoutException) { rstChannel.Abort(); } rstChannel = null; ValidateAndCacheServiceToken(negotiationState); serviceToken = negotiationState.ServiceToken; break; } } return(serviceToken); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } if (e is TimeoutException) { e = new TimeoutException(SR.Format(SR.ClientSecurityNegotiationTimeout, timeout, legs, timeLeft), e); } EndpointAddress temp = (negotiationState == null) ? null : negotiationState.RemoteAddress; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WrapExceptionIfRequired(e, temp, _issuerAddress)); } finally { Cleanup(rstChannel, negotiationState); } }