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
- RawKeyboardInputReport.cs
- WmlPhoneCallAdapter.cs
- SecuritySessionSecurityTokenProvider.cs
- ExpressionsCollectionConverter.cs
- ObjectDataSourceSelectingEventArgs.cs
- xsdvalidator.cs
- WindowManager.cs
- AnimationLayer.cs
- LogExtent.cs
- EdmSchemaAttribute.cs
- ControlCollection.cs
- Soap.cs
- ClientEventManager.cs
- WebHttpEndpoint.cs
- FileFormatException.cs
- AssociationProvider.cs
- PrePrepareMethodAttribute.cs
- XmlRootAttribute.cs
- WindowsListView.cs
- FontCacheLogic.cs
- SymmetricAlgorithm.cs
- FrameworkContentElement.cs
- TraceHandler.cs
- SqlBulkCopy.cs
- OleDbPermission.cs
- IssuedTokenClientCredential.cs
- ProtocolsConfigurationHandler.cs
- Debugger.cs
- ProfilePropertySettingsCollection.cs
- DataGridViewLinkColumn.cs
- UncommonField.cs
- MemoryStream.cs
- InputLangChangeRequestEvent.cs
- SystemTcpStatistics.cs
- ApplicationFileParser.cs
- SendActivityEventArgs.cs
- FileLogRecord.cs
- RichTextBoxAutomationPeer.cs
- FilterableData.cs
- HttpRuntime.cs
- QuaternionValueSerializer.cs
- StringReader.cs
- DiffuseMaterial.cs
- XsltArgumentList.cs
- StreamGeometry.cs
- ResourcesGenerator.cs
- FreeFormPanel.cs
- EasingKeyFrames.cs
- OracleDateTime.cs
- infer.cs
- FixedStringLookup.cs
- UrlUtility.cs
- XAMLParseException.cs
- RegexFCD.cs
- SafeSecurityHelper.cs
- Operator.cs
- UIElementPropertyUndoUnit.cs
- Brushes.cs
- Accessors.cs
- ColumnHeader.cs
- HtmlInputText.cs
- BitmapSizeOptions.cs
- DebugView.cs
- AudioFileOut.cs
- WsdlBuildProvider.cs
- SchemaElementLookUpTable.cs
- BoundField.cs
- PluggableProtocol.cs
- DefaultWorkflowTransactionService.cs
- DbConnectionHelper.cs
- RelOps.cs
- UserNameServiceElement.cs
- InfoCardRSAOAEPKeyExchangeFormatter.cs
- FileSystemEnumerable.cs
- NumericUpDownAcceleration.cs
- StateRuntime.cs
- SchemaNotation.cs
- RelationshipType.cs
- PropertyStore.cs
- ToggleButton.cs
- UserControlCodeDomTreeGenerator.cs
- MultipartContentParser.cs
- EnumMember.cs
- SapiGrammar.cs
- PolicyAssertionCollection.cs
- ViewValidator.cs
- WindowsListViewItemCheckBox.cs
- ClientType.cs
- StringHandle.cs
- LinkedResourceCollection.cs
- XmlDataImplementation.cs
- PaintEvent.cs
- PagerSettings.cs
- XmlHierarchyData.cs
- ImmutableObjectAttribute.cs
- CleanUpVirtualizedItemEventArgs.cs
- SettingsPropertyWrongTypeException.cs
- StyleBamlRecordReader.cs
- Permission.cs
- PasswordTextNavigator.cs