Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / GetTokenRequest.cs / 1 / GetTokenRequest.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading; //ManualResetEvent
using System.ComponentModel; //Win32Exception
using System.IO; //Stream
using System.Security.Cryptography;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
using System.Security.Principal;
using System.IdentityModel.Selectors;
using System.Net;
class GetTokenRequest : ClientUIRequest
{
public enum TrustDecision :byte
{
NoTrustDecision, // Indicating a recipient for whom a trust decision has never been made before
IsTrusted, // Indicating a recipient who has been trusted before
IsNotTrusted // Indicating a recipient who has been set to "untrusted" before
};
//
// inargs
//
InfoCardPolicy[ ] m_policyChain;
InfoCardPolicy m_policy;
//
// outargs
//
TokenDescriptor m_token;
ITokenFactory m_tokenFactory;
LedgerEntry m_ledgerEntry;
InfoCard m_selectedCard;
Recipient m_recipient;
//
// Required for synchronization for member variables between SelectCard
// and CreateToken
//
object m_createSecurityTokenDoneMonitor = new object();
//
// Set to true if CreateToken has finished processing
//
bool m_isProcessingComplete = true;
//
// Set to true if user proceeded to CreateToken after SelectCard
//
bool m_userProceededToCreateToken = false;
public GetTokenRequest( Process callingProcess, WindowsIdentity callingIdentity, InfoCardUIAgent uiAgent, IntPtr rpcHandle, Stream inArgs, Stream outArgs )
: base( callingProcess, callingIdentity, uiAgent, rpcHandle, inArgs, outArgs, InfoCardUIAgent.CallMode.GetToken, ExceptionList.AllNonFatal )
{
}
public TokenDescriptor Token
{
get { return m_token; }
}
public InfoCardPolicy Policy
{
get { return m_policy; }
protected set { m_policy = value; }
}
protected Recipient GetRecipient()
{
if ( null == m_recipient )
{
IDT.DebugAssert( null != m_policy, "null policy" );
m_recipient = new Recipient(
m_policy.Recipient,
false, // cert is not cached
m_policy.PrivacyPolicyVersion );
}
return m_recipient;
}
protected override void OnMarshalInArgs()
{
BinaryReader breader = new InfoCardBinaryReader( InArgs, Encoding.Unicode );
int policyLength = breader.ReadInt32();
//
// policyLength is specified by the rpc client, so we should perform a
// sanity check here
//
if( policyLength <= 0 || policyLength > CardSpaceSelector.MaxPolicyChainLength )
{
throw IDT.ThrowHelperError( new InfoCardArgumentException( SR.GetString( SR.InvalidPolicyLength ) ) );
}
m_policyChain = new InfoCardPolicy[ policyLength ];
for ( int i = 0; i < policyLength; i++ )
{
string recipientXml = Utility.DeserializeString( breader );
string issuerXml = Utility.DeserializeString( breader );
string policyXml = Utility.DeserializeString( breader );
string privacyPolicy = Utility.DeserializeString( breader );
uint privacyVersion = breader.ReadUInt32();
bool isManaged = breader.ReadBoolean();
m_policyChain[ i ] = PolicyFactory.CreatePolicyForGetTokenRequest(
breader,
recipientXml,
issuerXml,
policyXml,
isManaged );
//
// The "recipient" of any element in the chain refers to m_policyChain[ 0 ].
// So the certificate, the privacy policy URL, and version should
// be set to those belonging to m_policyChain[ 0 ]
//
if( 0 == i )
{
m_policyChain[ i ].SetRecipientInfo(
m_policyChain[ 0 ].ImmediateTokenRecipient,
privacyPolicy,
privacyVersion );
}
else
{
m_policyChain[ i ].SetRecipientInfo(
m_policyChain[ 0 ].ImmediateTokenRecipient,
m_policyChain[ 0 ].PrivacyPolicyLink,
m_policyChain[ 0 ].PrivacyPolicyVersion );
}
}
//
// See if the last policy in the chain is really the policy of a
// managed token provider that requires an imported managed card.
// If it is back up one sts.
//
int last = policyLength - 1;
if ( m_policyChain[ last ].IsManaged )
{
if( 0 == last )
{
//
// The number of policy elements is wrong. If 0 == last and last is managed,
// we are missing a policy element.
//
throw IDT.ThrowHelperError( new InfoCardArgumentException( SR.GetString( SR.InvalidPolicyLength ) ) );
}
last -= 1;
}
m_policy = m_policyChain[ last ];
m_policy.Validate();
}
protected override void OnProcess()
{
StartAndWaitForUIAgent();
}
protected override void OnMarshalOutArgs()
{
BinaryWriter bwriter = new BinaryWriter( OutArgs, Encoding.Unicode );
m_token.Write( bwriter );
//
// Don't dispose this crypto session. It get's disposed either when the client process has gone away,
// or the client explicitly closes it.
//
SymmetricAlgorithm symmetricProof = m_token.SymmetricProof;
CryptoSession cryptoSession = null;
if ( null == symmetricProof )
{
//
// GetPrivateCryptography - PRIVATE becuase this is to sign tokens in the self-issued case.
//
RSACryptoServiceProvider rsaIdentityWithPrivateKey =
GetPrivateCryptography();
//
// Transfer ownership of the rsa key pair to cryptoSession
//
cryptoSession = CryptoSession.Create(
CallerProcess,
m_token.ExpirationTime,
RequestorIdentity,
rsaIdentityWithPrivateKey );
}
else
{
cryptoSession = CryptoSession.Create(
CallerProcess,
m_token.ExpirationTime,
RequestorIdentity,
symmetricProof.Key );
}
cryptoSession.Write( bwriter );
}
protected RSACryptoServiceProvider GetPrivateCryptography()
{
return m_selectedCard.GetPrivateCryptography( GetRecipient().RecipientId );
}
//
// Summary:
// Dispose all user bound resources.
//
protected override void OnDisposeAsUser()
{
//
// Dispose the token info, as the keys with in
// must be released by the same identity that
// created them (the user).
//
base.OnDisposeAsUser();
if ( null != m_token )
{
m_token.Dispose();
m_token = null;
}
}
//
// Summary:
// Sets the state booleans
//
public void CancelSelectCard()
{
m_userProceededToCreateToken = false;
m_isProcessingComplete = true;
//
// A subsequent SelectCard thread should NOT have come in,
// no need to Pulse to wake it up.
//
}
//
// Optionally implement OnDisposeAsSystem
//
//
// Optionally implement OnHandleExceptions
//
//
// Remarks:
// Running on threadpool thread from BeginSelectCardRequest.
//
public Int32 SelectCard( InfoCard card, bool isSelfIssued )
{
//
// NB: Lock is equivalent to Monitor.Enter( m_createSecurityTokenDoneMonitor ).
// Note we're using Monitor.Wait on the same object below.
//
lock( m_createSecurityTokenDoneMonitor )
{
//
// m_userProceededToCreateToken m_isProcessingComplete
// True, True ---------------> Go ahead, createToken completed successfully
// True, False ---------------> Wait, User cancelled in createToken, wait till createToken also executes
// False, True ---------------> Go ahead, user cancelled in select card
// False, False ---------------> Go ahead, SelectCard completed but user cancelled before CreateToken
//
while( m_userProceededToCreateToken && !m_isProcessingComplete )
{
Monitor.Wait( m_createSecurityTokenDoneMonitor );
}
//
// Reset these
//
m_userProceededToCreateToken = false;
m_isProcessingComplete = false;
Int32 tokenCreationParamIndex = 0;
TokenCreationParameter createParam = null;
ServiceEndpoint ep = null;
IWebProxy proxy = null;
StoreConnection connection = StoreConnection.GetConnection();
try
{
card.Connection = connection;
if( isSelfIssued )
{
;
}
else
{
//
// As this is the most common case we will optimize the behaviour
// for a single auth type. In this case we will
// do the Mex operation just before creating the token. This will reduce
// the wait time between clicking submit and the appearing of the credential
// collection window.
//
if( 1 == card.CreationParameters.Count )
{
tokenCreationParamIndex = 0;
createParam = card.CreationParameters[ tokenCreationParamIndex ];
}
else
{
for( Int32 i = 0; i < card.CreationParameters.Count; i++ )
{
try
{
ep = RemoteTokenFactory.DoMexExchange( card.CreationParameters[ i ], this.UserProxy );
tokenCreationParamIndex = i;
createParam = card.CreationParameters[ tokenCreationParamIndex ];
break;
}
catch( TrustExchangeException )
{
//
// If this is the last auth type in the list we were not able to
// do a successful mex at any of the Epr's in the list. Throw an
// exception indicating failure to the UI.
//
if( i == card.CreationParameters.Count - 1 )
{
throw IDT.ThrowHelperError( new TrustExchangeException( SR.GetString( SR.InvalidServiceUri ) ) );
}
}
}
}
proxy = this.UserProxy;
}
}
finally
{
connection.Close();
}
m_tokenFactory = TokenFactoryFactory.Create( card, createParam, ep, proxy );
m_selectedCard = card;
return tokenCreationParamIndex;
}
}
//
// Summary:
// Cancels the outstanding token factory object if present.
//
public void CancelCreateSecurityToken()
{
//
// We are running on the main UI thread here, hence cannot take lock [Doing so will
// block the UI.]
//
if( null != m_tokenFactory )
{
m_tokenFactory.Abort();
}
m_userProceededToCreateToken = true;
//
// A subsequent SelectCard thread has should NOT have come in,
// no need to Pulse to wake that up.
//
}
//
// Remarks:
// Running on threadpool thread from BeginGetSecurityTokenRequest.
//
public DisplayToken CreateSecurityToken( TokenFactoryCredential credential, bool discloseOptional )
{
lock( m_createSecurityTokenDoneMonitor )
{
try
{
IDT.DebugAssert( null != m_tokenFactory, "No TokenFactory selected" );
IDT.DebugAssert( null != m_selectedCard, "No Card Selected" );
//
// Ledger must exist on the object before
// we attempt to create the token.
//
m_ledgerEntry = GetLedgerEntry();
if( null != m_token )
{
m_token.Dispose();
m_token = null;
}
using( credential )
{
m_token = m_tokenFactory.CreateToken( m_selectedCard, credential, m_policy, discloseOptional );
}
m_ledgerEntry.DisclosureDate = DateTime.UtcNow;
m_ledgerEntry.DisclosedClaims = new string[ m_token.DisclosedClaims.Count ];
for( int index = 0; index < m_token.DisclosedClaims.Count; index++ )
{
m_ledgerEntry.DisclosedClaims[ index ] = m_token.DisclosedClaims[ index ];
}
Array.Clear( m_selectedCard.Key, 0, m_selectedCard.Key.Length );
return m_token.DisplayToken;
}
finally
{
//
// Allow new SelectCard calls to get through.
//
m_isProcessingComplete = true;
m_userProceededToCreateToken = true;
//
// Wake up the subsequent SelectCard thread if it has already come in
//
Monitor.Pulse( m_createSecurityTokenDoneMonitor );
}
}
}
//
// Summary
// Retrieves or creates ledger entry.
//
// Returns
// Returns ledger entry.
//
// Note : the logic followed by this function is a little twisted.
// As we do not want a perf hit, we do not retrieve the complete ledger
// instead create a new ledger for the card with only the new or updated entry so
// that subsequent calls to TryGetLedgerEntry will return the correct
// ledger entry from the card ledger cache. This code is extremly fragile and should
// be changed so that ledger entry that is returned by this function is used in all
// subsequent token related calls.
//
private LedgerEntry GetLedgerEntry()
{
LedgerEntry entry = null;
StoreConnection connection = StoreConnection.GetConnection();
try
{
//
// Attempt to get an existing ledger entry.
//
entry = m_selectedCard.TryGetLedgerEntry( connection, m_policy.Recipient.GetIdentifier() );
//
// If an existing ledger entry doesn't exist then create a new ledger entry.
//
if( null == entry )
{
entry = m_selectedCard.CreateLedgerEntry( GetRecipient(), m_policy.ImmediateTokenRecipient.GetOrganizationIdentifier() );
}
else
{
m_selectedCard.CheckAndUpdateLedgerEntry( entry, m_policy.ImmediateTokenRecipient.GetOrganizationIdentifier() );
}
}
finally
{
connection.Close();
}
return entry;
}
//
// Summary
// Saves ledger entry to store.
//
public void SaveLedgerEntry()
{
StoreConnection con = StoreConnection.GetConnection();
try
{
con.BeginTransaction();
try
{
m_ledgerEntry.Save( con );
con.CommitTransaction();
}
catch
{
con.RollbackTransaction();
throw;
}
}
finally
{
con.Close();
}
}
}
}
// 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
- OptimalBreakSession.cs
- DataGridViewRowCancelEventArgs.cs
- PassportPrincipal.cs
- AsyncDataRequest.cs
- PingReply.cs
- MimeTextImporter.cs
- ColorConverter.cs
- ServiceInfo.cs
- ActivityWithResult.cs
- WorkflowOwnershipException.cs
- XmlAttributeAttribute.cs
- MobileControlPersister.cs
- CompilationLock.cs
- XXXOnTypeBuilderInstantiation.cs
- MatrixTransform3D.cs
- XPathParser.cs
- InputBindingCollection.cs
- precedingquery.cs
- ReleaseInstanceMode.cs
- LinkClickEvent.cs
- DurationConverter.cs
- Win32MouseDevice.cs
- LambdaCompiler.Generated.cs
- ProjectionRewriter.cs
- WebBrowser.cs
- AutoCompleteStringCollection.cs
- StrokeCollectionConverter.cs
- OracleRowUpdatingEventArgs.cs
- XmlConvert.cs
- TransmissionStrategy.cs
- PriorityItem.cs
- PrinterSettings.cs
- Duration.cs
- UIHelper.cs
- PersonalizationProviderHelper.cs
- TaskFactory.cs
- itemelement.cs
- FileDialog.cs
- CommonObjectSecurity.cs
- CatalogZoneBase.cs
- ShapeTypeface.cs
- ProfessionalColors.cs
- DecimalConstantAttribute.cs
- CompositeCollection.cs
- LateBoundBitmapDecoder.cs
- XmlText.cs
- ValidationSummaryDesigner.cs
- ViewSimplifier.cs
- TraceListeners.cs
- Drawing.cs
- ByteStreamGeometryContext.cs
- SQLResource.cs
- DescendentsWalkerBase.cs
- ComponentRenameEvent.cs
- RuntimeArgumentHandle.cs
- DbMetaDataColumnNames.cs
- ComplusEndpointConfigContainer.cs
- GridViewCancelEditEventArgs.cs
- XPathDocument.cs
- Source.cs
- BufferBuilder.cs
- PropertyItem.cs
- Stack.cs
- MenuBase.cs
- OdbcStatementHandle.cs
- RowVisual.cs
- ValidatorUtils.cs
- CatalogPart.cs
- Utility.cs
- ByteStreamGeometryContext.cs
- SafeNativeMethods.cs
- WebBaseEventKeyComparer.cs
- FixedPage.cs
- StructuralType.cs
- VisualState.cs
- ResourcesBuildProvider.cs
- RegexMatchCollection.cs
- MimeMultiPart.cs
- Triplet.cs
- codemethodreferenceexpression.cs
- TextServicesProperty.cs
- MessageContractMemberAttribute.cs
- ErrorFormatter.cs
- ClientScriptItemCollection.cs
- CfgParser.cs
- InitializationEventAttribute.cs
- EntitySqlQueryState.cs
- TraceFilter.cs
- TreeNodeConverter.cs
- ConstructorExpr.cs
- TemplatedWizardStep.cs
- EastAsianLunisolarCalendar.cs
- ResourceProperty.cs
- UIElement3DAutomationPeer.cs
- AttachInfo.cs
- DataTableMapping.cs
- XPathEmptyIterator.cs
- listitem.cs
- CodeMethodMap.cs
- MouseEventArgs.cs