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
- XmlNamedNodeMap.cs
- SubMenuStyle.cs
- ArraySubsetEnumerator.cs
- LeafCellTreeNode.cs
- SizeConverter.cs
- CreateParams.cs
- ArcSegment.cs
- DateTimeValueSerializer.cs
- listitem.cs
- Sql8ExpressionRewriter.cs
- DoubleCollection.cs
- File.cs
- SessionState.cs
- ZipIORawDataFileBlock.cs
- ClientScriptManager.cs
- MailMessage.cs
- XhtmlStyleClass.cs
- MobileControl.cs
- HyperLinkField.cs
- SqlDataSourceStatusEventArgs.cs
- QilCloneVisitor.cs
- IUnknownConstantAttribute.cs
- ScrollViewerAutomationPeer.cs
- ManagementOptions.cs
- XmlBinaryReader.cs
- SQLDecimal.cs
- SourceElementsCollection.cs
- XamlHttpHandlerFactory.cs
- MeasureData.cs
- EventToken.cs
- ObjectConverter.cs
- NativeMethods.cs
- CursorInteropHelper.cs
- IndexedGlyphRun.cs
- AssemblyHash.cs
- PagerSettings.cs
- CapabilitiesUse.cs
- ParamArrayAttribute.cs
- Rectangle.cs
- ContractsBCL.cs
- DbConnectionOptions.cs
- SafeNativeMethodsOther.cs
- ErrorCodes.cs
- BitmapFrameDecode.cs
- BooleanKeyFrameCollection.cs
- EntityDataSourceDataSelectionPanel.designer.cs
- ProxyFragment.cs
- FilterException.cs
- FontStretchConverter.cs
- XslAst.cs
- thaishape.cs
- FormViewUpdateEventArgs.cs
- ADConnectionHelper.cs
- List.cs
- ConstraintEnumerator.cs
- MessageQueuePermissionAttribute.cs
- LabelDesigner.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- ServiceDescriptionImporter.cs
- StringKeyFrameCollection.cs
- clipboard.cs
- SqlConnectionString.cs
- Triplet.cs
- SecurityImpersonationBehavior.cs
- FixedHyperLink.cs
- HebrewNumber.cs
- BufferedGraphics.cs
- _RequestCacheProtocol.cs
- DebugHandleTracker.cs
- ResourceDictionary.cs
- ISO2022Encoding.cs
- ExtenderHelpers.cs
- GeometryModel3D.cs
- SignatureToken.cs
- BaseParagraph.cs
- BitConverter.cs
- StylusPointProperty.cs
- XmlStreamNodeWriter.cs
- SqlBuffer.cs
- ToolZone.cs
- CriticalHandle.cs
- XmlHierarchicalEnumerable.cs
- GC.cs
- BindingGroup.cs
- TextElementCollection.cs
- TargetPerspective.cs
- BrowserTree.cs
- X509Utils.cs
- datacache.cs
- HtmlTableCell.cs
- CheckBoxAutomationPeer.cs
- MessageTransmitTraceRecord.cs
- EnumBuilder.cs
- FontEmbeddingManager.cs
- HorizontalAlignConverter.cs
- GridItem.cs
- SymLanguageType.cs
- XmlILStorageConverter.cs
- mediaeventargs.cs
- RelationshipType.cs