Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SspiNegotiationTokenAuthenticator.cs / 1 / SspiNegotiationTokenAuthenticator.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Security
{
using System.IdentityModel.Claims;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.IdentityModel.Policy;
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.Net;
using System.Xml;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ServiceModel.Diagnostics;
using System.Runtime.Serialization;
using CanonicalizationDriver = System.IdentityModel.CanonicalizationDriver;
using Psha1DerivedKeyGenerator = System.IdentityModel.Psha1DerivedKeyGenerator;
using XmlAttributeHolder = System.IdentityModel.XmlAttributeHolder;
abstract class SspiNegotiationTokenAuthenticator : NegotiationTokenAuthenticator
{
protected SspiNegotiationTokenAuthenticator()
: base()
{
}
// abstract methods
public abstract XmlDictionaryString NegotiationValueType { get; }
protected abstract ReadOnlyCollection ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation);
protected abstract SspiNegotiationTokenAuthenticatorState CreateSspiState(byte[] incomingBlob, string incomingValueTypeUri);
// helpers
protected virtual void IssueServiceToken(SspiNegotiationTokenAuthenticatorState sspiState, ReadOnlyCollection authorizationPolicies, out SecurityContextSecurityToken serviceToken, out WrappedKeySecurityToken proofToken,
out int issuedKeySize)
{
UniqueId contextId = SecurityUtils.GenerateUniqueId();
string id = SecurityUtils.GenerateId();
if (sspiState.RequestedKeySize == 0)
{
issuedKeySize = this.SecurityAlgorithmSuite.DefaultSymmetricKeyLength;
}
else
{
issuedKeySize = sspiState.RequestedKeySize;
}
byte[] key = new byte[issuedKeySize / 8];
CryptoHelper.FillRandomBytes(key);
DateTime effectiveTime = DateTime.UtcNow;
DateTime expirationTime = TimeoutHelper.Add(effectiveTime, this.ServiceTokenLifetime);
serviceToken = IssueSecurityContextToken(contextId, id, key, effectiveTime, expirationTime, authorizationPolicies, this.EncryptStateInServiceToken);
proofToken = new WrappedKeySecurityToken(string.Empty, key, sspiState.SspiNegotiation);
}
protected virtual void ValidateIncomingBinaryNegotiation(BinaryNegotiation incomingNego)
{
if (incomingNego == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToReceive)));
}
incomingNego.Validate(this.NegotiationValueType);
}
protected virtual BinaryNegotiation GetOutgoingBinaryNegotiation(ISspiNegotiation sspiNegotiation, byte[] outgoingBlob)
{
return new BinaryNegotiation(this.NegotiationValueType, outgoingBlob);
}
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(SspiNegotiationTokenAuthenticatorState sspiState, RequestSecurityToken rst)
{
MemoryStream stream = new MemoryStream();
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream);
rst.RequestSecurityTokenXml.WriteTo(writer);
writer.Flush();
AddToDigest(sspiState.NegotiationDigest, stream);
}
static void AddToDigest(SspiNegotiationTokenAuthenticatorState sspiState, RequestSecurityTokenResponse rstr, bool wasReceived)
{
MemoryStream stream = new MemoryStream();
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream);
if (wasReceived)
{
rstr.RequestSecurityTokenResponseXml.WriteTo(writer);
}
else
{
rstr.WriteTo(writer);
}
writer.Flush();
AddToDigest(sspiState.NegotiationDigest, stream);
}
static byte[] ComputeAuthenticator(SspiNegotiationTokenAuthenticatorState sspiState, byte[] key)
{
byte[] negotiationHash;
lock (sspiState.NegotiationDigest)
{
sspiState.NegotiationDigest.TransformFinalBlock(CryptoHelper.EmptyBuffer, 0, 0);
negotiationHash = sspiState.NegotiationDigest.Hash;
}
Psha1DerivedKeyGenerator generator = new Psha1DerivedKeyGenerator(key);
return generator.GenerateDerivedKey(SecurityUtils.CombinedHashLabel, negotiationHash, SecurityNegotiationConstants.NegotiationAuthenticatorSize, 0);
}
// overrides
protected override bool IsMultiLegNegotiation
{
get
{
return true;
}
}
protected override Binding GetNegotiationBinding(Binding binding)
{
return binding;
}
protected override MessageFilter GetListenerFilter()
{
return new SspiNegotiationFilter(this);
}
protected override BodyWriter ProcessRequestSecurityToken(Message request, RequestSecurityToken requestSecurityToken, out SspiNegotiationTokenAuthenticatorState negotiationState)
{
if (request == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request");
}
if (requestSecurityToken == null)
{
throw TraceUtility.ThrowHelperArgumentNull("requestSecurityToken", request);
}
if (requestSecurityToken.RequestType != null && requestSecurityToken.RequestType != this.StandardsManager.TrustDriver.RequestTypeIssue)
{
throw TraceUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidRstRequestType, requestSecurityToken.RequestType)), request);
}
BinaryNegotiation incomingNego = requestSecurityToken.GetBinaryNegotiation();
ValidateIncomingBinaryNegotiation(incomingNego);
negotiationState = CreateSspiState(incomingNego.GetNegotiationData(), incomingNego.ValueTypeUri);
AddToDigest(negotiationState, requestSecurityToken);
negotiationState.Context = requestSecurityToken.Context;
if (requestSecurityToken.KeySize != 0)
{
WSTrust.Driver.ValidateRequestedKeySize(requestSecurityToken.KeySize, this.SecurityAlgorithmSuite);
}
negotiationState.RequestedKeySize = requestSecurityToken.KeySize;
string appliesToName;
string appliesToNamespace;
requestSecurityToken.GetAppliesToQName(out appliesToName, out appliesToNamespace);
if (appliesToName == AddressingStrings.EndpointReference && appliesToNamespace == request.Version.Addressing.Namespace)
{
DataContractSerializer serializer;
if (request.Version.Addressing == AddressingVersion.WSAddressing10)
{
serializer = DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddress10), DataContractSerializerDefaults.MaxItemsInObjectGraph);
negotiationState.AppliesTo = requestSecurityToken.GetAppliesTo(serializer).ToEndpointAddress();
}
else if (request.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
{
serializer = DataContractSerializerDefaults.CreateSerializer(typeof(EndpointAddressAugust2004), DataContractSerializerDefaults.MaxItemsInObjectGraph);
negotiationState.AppliesTo = requestSecurityToken.GetAppliesTo(serializer).ToEndpointAddress();
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, request.Version.Addressing)));
}
negotiationState.AppliesToSerializer = serializer;
}
return ProcessNegotiation(negotiationState, request, incomingNego);
}
protected override BodyWriter ProcessRequestSecurityTokenResponse(SspiNegotiationTokenAuthenticatorState negotiationState, Message request, RequestSecurityTokenResponse requestSecurityTokenResponse)
{
if (request == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("request");
}
if (requestSecurityTokenResponse == null)
{
throw TraceUtility.ThrowHelperArgumentNull("requestSecurityTokenResponse", request);
}
if (requestSecurityTokenResponse.Context != negotiationState.Context)
{
throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.BadSecurityNegotiationContext)), request);
}
AddToDigest(negotiationState, requestSecurityTokenResponse, true);
BinaryNegotiation incomingNego = requestSecurityTokenResponse.GetBinaryNegotiation();
ValidateIncomingBinaryNegotiation(incomingNego);
return ProcessNegotiation(negotiationState, request, incomingNego);
}
BodyWriter ProcessNegotiation(SspiNegotiationTokenAuthenticatorState negotiationState, Message incomingMessage, BinaryNegotiation incomingNego)
{
ISspiNegotiation sspiNegotiation = negotiationState.SspiNegotiation;
byte[] outgoingBlob = sspiNegotiation.GetOutgoingBlob(incomingNego.GetNegotiationData());
if (sspiNegotiation.IsValidContext == false)
{
throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation)), incomingMessage);
}
// if there is no blob to send back the nego must be complete from the server side
if (outgoingBlob == null && sspiNegotiation.IsCompleted == false)
{
throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToSend)), incomingMessage);
}
BinaryNegotiation outgoingBinaryNegotiation;
if (outgoingBlob != null)
{
outgoingBinaryNegotiation = GetOutgoingBinaryNegotiation(sspiNegotiation, outgoingBlob);
}
else
{
outgoingBinaryNegotiation = null;
}
BodyWriter replyBody;
if (sspiNegotiation.IsCompleted)
{
ReadOnlyCollection authorizationPolicies = ValidateSspiNegotiation(sspiNegotiation);
SecurityContextSecurityToken serviceToken;
WrappedKeySecurityToken proofToken;
int issuedKeySize;
IssueServiceToken(negotiationState, authorizationPolicies, out serviceToken, out proofToken, out issuedKeySize);
negotiationState.SetServiceToken(serviceToken);
SecurityKeyIdentifierClause externalTokenReference = this.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.External);
SecurityKeyIdentifierClause internalTokenReference = this.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.Internal);
RequestSecurityTokenResponse dummyRstr = new RequestSecurityTokenResponse(this.StandardsManager);
dummyRstr.Context = negotiationState.Context;
dummyRstr.KeySize = issuedKeySize;
dummyRstr.TokenType = this.SecurityContextTokenUri;
if (outgoingBinaryNegotiation != null)
{
dummyRstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
}
dummyRstr.RequestedUnattachedReference = externalTokenReference;
dummyRstr.RequestedAttachedReference = internalTokenReference;
dummyRstr.SetLifetime(serviceToken.ValidFrom, serviceToken.ValidTo);
if (negotiationState.AppliesTo != null)
{
if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressing10)
{
dummyRstr.SetAppliesTo(EndpointAddress10.FromEndpointAddress(
negotiationState.AppliesTo),
negotiationState.AppliesToSerializer);
}
else if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
{
dummyRstr.SetAppliesTo(EndpointAddressAugust2004.FromEndpointAddress(
negotiationState.AppliesTo),
negotiationState.AppliesToSerializer);
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, incomingMessage.Version.Addressing)));
}
}
dummyRstr.MakeReadOnly();
AddToDigest(negotiationState, dummyRstr, false);
RequestSecurityTokenResponse negotiationRstr = new RequestSecurityTokenResponse(this.StandardsManager);
negotiationRstr.RequestedSecurityToken = serviceToken;
negotiationRstr.RequestedProofToken = proofToken;
negotiationRstr.Context = negotiationState.Context;
negotiationRstr.KeySize = issuedKeySize;
negotiationRstr.TokenType = this.SecurityContextTokenUri;
if (outgoingBinaryNegotiation != null)
{
negotiationRstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
}
negotiationRstr.RequestedAttachedReference = internalTokenReference;
negotiationRstr.RequestedUnattachedReference = externalTokenReference;
if (negotiationState.AppliesTo != null)
{
if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressing10)
{
negotiationRstr.SetAppliesTo(
EndpointAddress10.FromEndpointAddress(negotiationState.AppliesTo),
negotiationState.AppliesToSerializer);
}
else if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
{
negotiationRstr.SetAppliesTo(
EndpointAddressAugust2004.FromEndpointAddress(negotiationState.AppliesTo),
negotiationState.AppliesToSerializer);
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, incomingMessage.Version.Addressing)));
}
}
negotiationRstr.MakeReadOnly();
byte[] authenticator = ComputeAuthenticator(negotiationState, serviceToken.GetKeyBytes());
RequestSecurityTokenResponse authenticatorRstr = new RequestSecurityTokenResponse(this.StandardsManager);
authenticatorRstr.Context = negotiationState.Context;
authenticatorRstr.SetAuthenticator(authenticator);
authenticatorRstr.MakeReadOnly();
List rstrList = new List(2);
rstrList.Add(negotiationRstr);
rstrList.Add(authenticatorRstr);
replyBody = new RequestSecurityTokenResponseCollection(rstrList, this.StandardsManager);
}
else
{
RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(this.StandardsManager);
rstr.Context = negotiationState.Context;
rstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
rstr.MakeReadOnly();
AddToDigest(negotiationState, rstr, false);
replyBody = rstr;
}
return replyBody;
}
class SspiNegotiationFilter : HeaderFilter
{
SspiNegotiationTokenAuthenticator authenticator;
public SspiNegotiationFilter(SspiNegotiationTokenAuthenticator authenticator)
{
this.authenticator = authenticator;
}
public override bool Match(Message message)
{
if (message.Headers.Action == authenticator.RequestSecurityTokenAction.Value
|| message.Headers.Action == authenticator.RequestSecurityTokenResponseAction.Value)
{
return !SecurityVersion.Default.DoesMessageContainSecurityHeader(message);
}
else
{
return false;
}
}
}
}
}
// 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
- SqlException.cs
- ListBindableAttribute.cs
- DrawingBrush.cs
- CodeDelegateCreateExpression.cs
- _NegotiateClient.cs
- DESCryptoServiceProvider.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- TCPClient.cs
- ExpressionBindingCollection.cs
- Int16.cs
- SchemaTableOptionalColumn.cs
- DataPagerField.cs
- KoreanCalendar.cs
- DataTable.cs
- ScriptManager.cs
- LocatorPart.cs
- SourceLineInfo.cs
- ListViewGroupConverter.cs
- SortKey.cs
- MessageBox.cs
- JsonEnumDataContract.cs
- TraceHandler.cs
- ButtonAutomationPeer.cs
- HttpAsyncResult.cs
- EndpointDiscoveryMetadata11.cs
- ClientApiGenerator.cs
- DefaultTraceListener.cs
- ExtensibleClassFactory.cs
- TraceFilter.cs
- RootProfilePropertySettingsCollection.cs
- SpecularMaterial.cs
- ProcessHostConfigUtils.cs
- SupportsEventValidationAttribute.cs
- LinkClickEvent.cs
- CodeVariableDeclarationStatement.cs
- NotSupportedException.cs
- Int32CollectionValueSerializer.cs
- RenderContext.cs
- GridToolTip.cs
- EdmSchemaAttribute.cs
- AuthStoreRoleProvider.cs
- WeakEventTable.cs
- CaseStatement.cs
- MemberProjectedSlot.cs
- FlowchartDesigner.xaml.cs
- SmiMetaDataProperty.cs
- ping.cs
- MetadataSerializer.cs
- Restrictions.cs
- TypeToken.cs
- ConstantProjectedSlot.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- TranslateTransform3D.cs
- SynchronizedInputHelper.cs
- ComponentConverter.cs
- ApplicationBuildProvider.cs
- PropagationProtocolsTracing.cs
- ReadContentAsBinaryHelper.cs
- Query.cs
- HtmlInputReset.cs
- PageThemeCodeDomTreeGenerator.cs
- WebPartMenuStyle.cs
- UnhandledExceptionEventArgs.cs
- TypeConstant.cs
- DataGridViewComboBoxCell.cs
- ByteAnimationUsingKeyFrames.cs
- DataPagerCommandEventArgs.cs
- SrgsElement.cs
- Misc.cs
- DebugView.cs
- SafeRightsManagementHandle.cs
- DataObjectMethodAttribute.cs
- WebPartVerb.cs
- Message.cs
- HostingPreferredMapPath.cs
- Vector3DValueSerializer.cs
- SqlSupersetValidator.cs
- MetadataFile.cs
- UnsignedPublishLicense.cs
- XmlReader.cs
- UIElement3D.cs
- ReaderWriterLock.cs
- SqlAliasesReferenced.cs
- Fonts.cs
- ZipIOExtraFieldPaddingElement.cs
- NumericUpDownAccelerationCollection.cs
- RectangleConverter.cs
- HwndKeyboardInputProvider.cs
- Composition.cs
- NTAccount.cs
- SolidColorBrush.cs
- XmlStringTable.cs
- ButtonChrome.cs
- ToolStripDropDownButton.cs
- GetPageNumberCompletedEventArgs.cs
- DispatcherSynchronizationContext.cs
- ScriptComponentDescriptor.cs
- RotateTransform3D.cs
- DataGridViewCellStyleContentChangedEventArgs.cs
- HtmlInputRadioButton.cs