Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SspiNegotiationTokenProvider.cs / 1 / SspiNegotiationTokenProvider.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Security { using System.IdentityModel.Claims; using System.ServiceModel; using System.IdentityModel.Policy; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.Security.Principal; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.ServiceModel.Security.Tokens; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ServiceModel.Channels; using System.Xml; using System.Net; using System.Text; using System.IO; using System.Diagnostics; using System.Runtime.Serialization; using System.ServiceModel.Diagnostics; using CanonicalizationDriver = System.IdentityModel.CanonicalizationDriver; using Psha1DerivedKeyGenerator = System.IdentityModel.Psha1DerivedKeyGenerator; using SafeFreeCredentials = System.IdentityModel.SafeFreeCredentials; abstract class SspiNegotiationTokenProvider : NegotiationTokenProvider{ bool negotiateTokenOnOpen; protected SspiNegotiationTokenProvider() : base() { } public bool NegotiateTokenOnOpen { get { return this.negotiateTokenOnOpen; } set { this.CommunicationObject.ThrowIfDisposedOrImmutable(); this.negotiateTokenOnOpen = value; } } // SspiNegotiationTokenProvider abstract methods protected abstract ReadOnlyCollection ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation); public abstract XmlDictionaryString NegotiationValueType { get; } public override void OnOpen(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.EnsureEndpointAddressDoesNotRequireEncryption(this.TargetAddress); base.OnOpen(timeoutHelper.RemainingTime()); if (this.negotiateTokenOnOpen) { this.DoNegotiation(timeoutHelper.RemainingTime()); } } protected override IChannelFactory GetNegotiationChannelFactory(IChannelFactory transportChannelFactory, ChannelBuilder channelBuilder) { return transportChannelFactory; } // helper methods void ValidateIncomingBinaryNegotiation(BinaryNegotiation incomingNego) { incomingNego.Validate(NegotiationValueType); } static void AddToDigest(HashAlgorithm negotiationDigest, Stream stream) { stream.Flush(); stream.Seek(0, SeekOrigin.Begin); CanonicalizationDriver canonicalizer = new CanonicalizationDriver(); canonicalizer.SetInput(stream); byte[] canonicalizedData = canonicalizer.GetBytes(); lock (negotiationDigest) { negotiationDigest.TransformBlock(canonicalizedData, 0, canonicalizedData.Length, canonicalizedData, 0); } } static void AddToDigest(SspiNegotiationTokenProviderState sspiState, RequestSecurityToken rst) { MemoryStream stream = new MemoryStream(); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream); rst.WriteTo(writer); writer.Flush(); AddToDigest(sspiState.NegotiationDigest, stream); } void AddToDigest(SspiNegotiationTokenProviderState sspiState, RequestSecurityTokenResponse rstr, bool wasReceived, bool isFinalRstr) { MemoryStream stream = new MemoryStream(); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream); if (!wasReceived) { rstr.WriteTo(writer); } else { if (!isFinalRstr) { rstr.RequestSecurityTokenResponseXml.WriteTo(writer); } else { XmlElement rstrClone = (XmlElement) rstr.RequestSecurityTokenResponseXml.CloneNode(true); List nodesToRemove = new List (2); for (int i = 0; i < rstrClone.ChildNodes.Count; ++i) { XmlNode child = (rstrClone.ChildNodes[i]); if (this.StandardsManager.TrustDriver.IsRequestedSecurityTokenElement(child.LocalName, child.NamespaceURI)) { nodesToRemove.Add(child); } else if (this.StandardsManager.TrustDriver.IsRequestedProofTokenElement(child.LocalName, child.NamespaceURI)) { nodesToRemove.Add(child); } } for (int i = 0; i < nodesToRemove.Count; ++i) { rstrClone.RemoveChild(nodesToRemove[i]); } rstrClone.WriteTo(writer); } } writer.Flush(); AddToDigest(sspiState.NegotiationDigest, stream); } static bool IsCorrectAuthenticator(SspiNegotiationTokenProviderState sspiState, byte[] proofKey, byte[] serverAuthenticator) { byte[] negotiationHash; lock (sspiState.NegotiationDigest) { sspiState.NegotiationDigest.TransformFinalBlock(CryptoHelper.EmptyBuffer, 0, 0); negotiationHash = sspiState.NegotiationDigest.Hash; } Psha1DerivedKeyGenerator generator = new Psha1DerivedKeyGenerator(proofKey); byte[] clientAuthenticator = generator.GenerateDerivedKey(SecurityUtils.CombinedHashLabel, negotiationHash, SecurityNegotiationConstants.NegotiationAuthenticatorSize, 0); if (clientAuthenticator.Length != serverAuthenticator.Length) { return false; } for (int i = 0; i < clientAuthenticator.Length; ++i) { if (clientAuthenticator[i] != serverAuthenticator[i]) { return false; } } return true; } BodyWriter PrepareRst(SspiNegotiationTokenProviderState sspiState, byte[] outgoingBlob) { RequestSecurityToken rst = new RequestSecurityToken(this.StandardsManager); rst.Context = sspiState.Context; rst.TokenType = this.StandardsManager.SecureConversationDriver.TokenTypeUri; rst.SetBinaryNegotiation(new BinaryNegotiation(NegotiationValueType, outgoingBlob)); rst.KeySize = this.SecurityAlgorithmSuite.DefaultSymmetricKeyLength; rst.MakeReadOnly(); AddToDigest(sspiState, rst); return rst; } BodyWriter PrepareRstr(SspiNegotiationTokenProviderState sspiState, byte[] outgoingBlob) { RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(this.StandardsManager); rstr.Context = sspiState.Context; rstr.SetBinaryNegotiation(new BinaryNegotiation(NegotiationValueType, outgoingBlob)); rstr.MakeReadOnly(); AddToDigest(sspiState, rstr, false, false); return rstr; } protected override BodyWriter GetFirstOutgoingMessageBody(SspiNegotiationTokenProviderState sspiState, out MessageProperties messageProperties) { messageProperties = null; ISspiNegotiation sspiNegotiation = sspiState.SspiNegotiation; byte[] outgoingBlob = sspiNegotiation.GetOutgoingBlob(null); if (outgoingBlob == null && sspiNegotiation.IsCompleted == false) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToSend))); } return PrepareRst(sspiState, outgoingBlob); } protected override BodyWriter GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState) { try { ThrowIfFault(incomingMessage, this.TargetAddress); } catch (FaultException fault) { if (fault.Code.IsSenderFault) { if (fault.Code.SubCode.Name == TrustApr2004Strings.FailedAuthenticationFaultCode || fault.Code.SubCode.Name == TrustFeb2005Strings.FailedAuthenticationFaultCode) throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.AuthenticationOfClientFailed), fault), incomingMessage); throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.FailedSspiNegotiation), fault), incomingMessage); } else { throw; } } RequestSecurityTokenResponse negotiationRstr = null; RequestSecurityTokenResponse authenticatorRstr = null; XmlDictionaryReader bodyReader = incomingMessage.GetReaderAtBodyContents(); using (bodyReader) { if (this.StandardsManager.TrustDriver.IsAtRequestSecurityTokenResponseCollection(bodyReader)) { RequestSecurityTokenResponseCollection rstrCollection = this.StandardsManager.TrustDriver.CreateRequestSecurityTokenResponseCollection(bodyReader); using (IEnumerator enumerator = rstrCollection.RstrCollection.GetEnumerator()) { enumerator.MoveNext(); negotiationRstr = enumerator.Current; if (enumerator.MoveNext()) { authenticatorRstr = enumerator.Current; } } if (authenticatorRstr == null) { throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.AuthenticatorNotPresentInRSTRCollection)), incomingMessage); } else if (authenticatorRstr.Context != negotiationRstr.Context) { throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.RSTRAuthenticatorHasBadContext)), incomingMessage); } AddToDigest(sspiState, negotiationRstr, true, true); } else if (this.StandardsManager.TrustDriver.IsAtRequestSecurityTokenResponse(bodyReader)) { negotiationRstr = RequestSecurityTokenResponse.CreateFrom(this.StandardsManager, bodyReader); AddToDigest(sspiState, negotiationRstr, true, false); } else { this.StandardsManager.TrustDriver.OnRSTRorRSTRCMissingException(); } incomingMessage.ReadFromBodyContentsToEnd(bodyReader); } if (negotiationRstr.Context != sspiState.Context) { throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.BadSecurityNegotiationContext)), incomingMessage); } BinaryNegotiation incomingBinaryNego = negotiationRstr.GetBinaryNegotiation(); byte[] incomingBlob; if (incomingBinaryNego != null) { ValidateIncomingBinaryNegotiation(incomingBinaryNego); incomingBlob = incomingBinaryNego.GetNegotiationData(); } else { incomingBlob = null; } BodyWriter nextMessageBody; if (incomingBlob == null && sspiState.SspiNegotiation.IsCompleted == false) { throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToReceive)), incomingMessage); } else if (incomingBlob == null && sspiState.SspiNegotiation.IsCompleted == true) { // the incoming RSTR must have the negotiated token OnNegotiationComplete(sspiState, negotiationRstr, authenticatorRstr); nextMessageBody = null; } else { // we got an incoming blob. Process it and see if there is an outgoing blob byte[] outgoingBlob = sspiState.SspiNegotiation.GetOutgoingBlob(incomingBlob); if (outgoingBlob == null && sspiState.SspiNegotiation.IsCompleted == false) { throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToSend)), incomingMessage); } else if (outgoingBlob == null && sspiState.SspiNegotiation.IsCompleted == true) { // the incoming RSTR had the last blob. It must have the token too this.OnNegotiationComplete(sspiState, negotiationRstr, authenticatorRstr); nextMessageBody = null; } else { nextMessageBody = PrepareRstr(sspiState, outgoingBlob); } } return nextMessageBody; } void OnNegotiationComplete(SspiNegotiationTokenProviderState sspiState, RequestSecurityTokenResponse negotiationRstr, RequestSecurityTokenResponse authenticatorRstr) { ISspiNegotiation sspiNegotiation = sspiState.SspiNegotiation; ReadOnlyCollection authorizationPolicies = ValidateSspiNegotiation(sspiNegotiation); // the negotiation has completed successfully - the service token needs to be extracted from the // negotiationRstr SecurityTokenResolver tokenResolver = new SspiSecurityTokenResolver(sspiNegotiation); GenericXmlSecurityToken serviceToken = negotiationRstr.GetIssuedToken(tokenResolver, EmptyReadOnlyCollection .Instance, SecurityKeyEntropyMode.ServerEntropy, null, this.SecurityContextTokenUri, authorizationPolicies, 0, false); if (serviceToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoServiceTokenReceived))); } WrappedKeySecurityToken wrappedToken = (serviceToken.ProofToken as WrappedKeySecurityToken); if (wrappedToken == null || wrappedToken.WrappingAlgorithm != sspiNegotiation.KeyEncryptionAlgorithm) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.ProofTokenWasNotWrappedCorrectly))); } byte[] proofKey = wrappedToken.GetWrappedKey(); if (authenticatorRstr == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.RSTRAuthenticatorNotPresent))); } byte[] serverAuthenticator = authenticatorRstr.GetAuthenticator(); if (serverAuthenticator == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.RSTRAuthenticatorNotPresent))); } if (!IsCorrectAuthenticator(sspiState, proofKey, serverAuthenticator)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.RSTRAuthenticatorIncorrect))); } sspiState.SetServiceToken(serviceToken); } class SspiSecurityTokenResolver : SecurityTokenResolver, ISspiNegotiationInfo { ISspiNegotiation sspiNegotiation; public SspiSecurityTokenResolver(ISspiNegotiation sspiNegotiation) { this.sspiNegotiation = sspiNegotiation; } public ISspiNegotiation SspiNegotiation { get { return this.sspiNegotiation; } } protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token) { token = null; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token) { token = null; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key) { key = null; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } } } class SspiIssuanceChannelParameter { bool getTokenOnOpen; SafeFreeCredentials credentialsHandle; public SspiIssuanceChannelParameter(bool getTokenOnOpen, SafeFreeCredentials credentialsHandle) { this.getTokenOnOpen = getTokenOnOpen; this.credentialsHandle = credentialsHandle; } public bool GetTokenOnOpen { get { return this.getTokenOnOpen; } } public SafeFreeCredentials CredentialsHandle { get { return this.credentialsHandle; } } } interface ISspiNegotiationInfo { ISspiNegotiation SspiNegotiation { get; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ParameterElementCollection.cs
- UnmanagedMemoryAccessor.cs
- DeobfuscatingStream.cs
- Parser.cs
- MimeObjectFactory.cs
- AndCondition.cs
- ControlBindingsCollection.cs
- SetterBase.cs
- Crc32.cs
- IIS7UserPrincipal.cs
- DataTable.cs
- NativeMsmqMessage.cs
- GridItemPatternIdentifiers.cs
- ExtendedProtectionPolicy.cs
- BinaryKeyIdentifierClause.cs
- ClientSideQueueItem.cs
- BitmapEffect.cs
- MsmqTransportElement.cs
- WindowsAuthenticationEventArgs.cs
- ObjectView.cs
- SystemGatewayIPAddressInformation.cs
- CrossContextChannel.cs
- FactoryRecord.cs
- Point4DConverter.cs
- prompt.cs
- ConfigurationSchemaErrors.cs
- ValidationSummary.cs
- UInt64.cs
- BackStopAuthenticationModule.cs
- dsa.cs
- SRGSCompiler.cs
- ObjectStateManager.cs
- WebRequest.cs
- SemaphoreSecurity.cs
- Content.cs
- StateMachineExecutionState.cs
- BinaryFormatterWriter.cs
- CorrelationManager.cs
- EventLogPermission.cs
- TemplatedWizardStep.cs
- TraceListener.cs
- ContentTextAutomationPeer.cs
- TextWriterTraceListener.cs
- CrossSiteScriptingValidation.cs
- StateDesigner.LayoutSelectionGlyph.cs
- TypeConverterValueSerializer.cs
- OciHandle.cs
- XmlEntity.cs
- StylusButtonCollection.cs
- ContainerControlDesigner.cs
- ConfigurationException.cs
- PlatformNotSupportedException.cs
- DataTable.cs
- ReachSerializer.cs
- FlagsAttribute.cs
- MatrixStack.cs
- DataGridViewLinkColumn.cs
- ProcessHostMapPath.cs
- ObjectReaderCompiler.cs
- cookieexception.cs
- CompositeControl.cs
- ShapingWorkspace.cs
- LogicalExpressionEditor.cs
- SystemBrushes.cs
- SafeRightsManagementQueryHandle.cs
- AssertFilter.cs
- ImmutableCollection.cs
- TCPListener.cs
- ListItem.cs
- SByteStorage.cs
- TableNameAttribute.cs
- FileLogRecordEnumerator.cs
- TrackingRecord.cs
- BitmapPalette.cs
- ListViewInsertedEventArgs.cs
- RealizationContext.cs
- NegotiateStream.cs
- DataSvcMapFile.cs
- ImageClickEventArgs.cs
- DeviceSpecificDialogCachedState.cs
- EncryptedPackageFilter.cs
- FontClient.cs
- TextRunCacheImp.cs
- SourceItem.cs
- BoundColumn.cs
- DataKey.cs
- StartUpEventArgs.cs
- _TLSstream.cs
- HitTestResult.cs
- SqlException.cs
- ContractComponent.cs
- securitycriticaldataformultiplegetandset.cs
- TableLayoutSettingsTypeConverter.cs
- TemplateXamlParser.cs
- ButtonColumn.cs
- versioninfo.cs
- XmlWhitespace.cs
- InvalidAsynchronousStateException.cs
- XamlBuildTaskServices.cs
- MobileControlsSectionHandler.cs