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
- ReadOnlyCollection.cs
- XmlMtomReader.cs
- InspectionWorker.cs
- PropertyCollection.cs
- DnsPermission.cs
- TypedReference.cs
- ObjectSecurity.cs
- CodeExporter.cs
- InvalidComObjectException.cs
- SqlPersonalizationProvider.cs
- XmlNodeComparer.cs
- Margins.cs
- DaylightTime.cs
- SafeNativeMethods.cs
- formatstringdialog.cs
- ProfileSettingsCollection.cs
- ZipIOExtraFieldZip64Element.cs
- OdbcParameterCollection.cs
- FlowLayoutSettings.cs
- TreeWalkHelper.cs
- Line.cs
- ColumnMap.cs
- Descriptor.cs
- TransactionState.cs
- BinaryFormatterSinks.cs
- KeyedHashAlgorithm.cs
- ErrorFormatter.cs
- RowUpdatingEventArgs.cs
- TextInfo.cs
- SnapshotChangeTrackingStrategy.cs
- DataMember.cs
- XmlMembersMapping.cs
- _ConnectionGroup.cs
- AssemblyBuilder.cs
- localization.cs
- TabOrder.cs
- PieceDirectory.cs
- DataList.cs
- ProviderConnectionPoint.cs
- HitTestWithGeometryDrawingContextWalker.cs
- SqlDataSourceStatusEventArgs.cs
- JsonReaderDelegator.cs
- KeyPressEvent.cs
- Bezier.cs
- AutoGeneratedFieldProperties.cs
- UnitySerializationHolder.cs
- ColorConvertedBitmap.cs
- Missing.cs
- MenuItemBindingCollection.cs
- DataPagerFieldItem.cs
- PlatformCulture.cs
- ProxyAttribute.cs
- ProgressBar.cs
- ChangeConflicts.cs
- BuildDependencySet.cs
- AlternateView.cs
- WeakReference.cs
- EncoderReplacementFallback.cs
- HotSpot.cs
- mansign.cs
- ExplicitDiscriminatorMap.cs
- SystemIcmpV6Statistics.cs
- EntityDataSourceStatementEditor.cs
- WeakHashtable.cs
- TableLayoutColumnStyleCollection.cs
- OperatingSystemVersionCheck.cs
- SourceLineInfo.cs
- SR.cs
- CodeTypeMember.cs
- Parameter.cs
- DoubleLinkList.cs
- DataGridViewToolTip.cs
- TextServicesPropertyRanges.cs
- StringConverter.cs
- WindowsFormsLinkLabel.cs
- BreakRecordTable.cs
- AudioFormatConverter.cs
- EngineSite.cs
- WindowsPrincipal.cs
- SafeCryptoHandles.cs
- PerfCounterSection.cs
- DataStreamFromComStream.cs
- IndependentlyAnimatedPropertyMetadata.cs
- XmlStringTable.cs
- TextInfo.cs
- Int32CollectionValueSerializer.cs
- ProtocolViolationException.cs
- XamlPathDataSerializer.cs
- HttpListener.cs
- DataGridAutoFormatDialog.cs
- Object.cs
- RelatedEnd.cs
- OpenTypeMethods.cs
- BuilderPropertyEntry.cs
- IPPacketInformation.cs
- InstanceNotFoundException.cs
- _BasicClient.cs
- EventSource.cs
- DetailsViewUpdatedEventArgs.cs
- EdmToObjectNamespaceMap.cs