/// <summary> /// </summary> /// /// <remarks> /// In order to avoid unnecessary authentication actions, it is /// expected that the caller will first call /// <cref name="IsAuthenticationExpired"/> before calling this. /// </remarks> /// /// <param name="result"> /// The authenticated session token. /// </param> /// internal void Update( CreateAuthenticationTokenResult result) { LastRefreshed = DateTime.UtcNow; RefreshCounter++; AuthenticationResult = result; IsAuthenticationResultExpired = false; }
/// <summary> /// Gets a value indicating whether the result contains a successfully /// authenticated token. /// </summary> /// /// <param name="result"> /// The result to query. /// </param> /// /// <returns> /// <b>true</b> if the result contains a successfully /// authenticated token; otherwise, <b>false</b>. /// </returns> /// internal static bool IsAuthenticated(CreateAuthenticationTokenResult result) { return (result != null && result.Status == AuthenticationTokenCreationStatus.Success && result.ApplicationRecordAuthorizationAction == ApplicationRecordAuthorizationAction.NoActionRequired && !String.IsNullOrEmpty(result.AuthenticationToken)); }
/// <summary> /// Gets one or more authorization tokens from the response XML. /// </summary> /// /// <param name="navTokenIterator"> /// The path to the token or tokens. /// </param> /// /// <param name="createAuthTokenResult"> /// The token results. /// </param> /// private static void GetTokenByParseResponse( XPathNodeIterator navTokenIterator, CreateAuthenticationTokenResult createAuthTokenResult) { foreach (XPathNavigator tokenNav in navTokenIterator) { Guid applicationId = new Guid(tokenNav.GetAttribute("app-id", String.Empty)); ApplicationRecordAuthorizationAction action = ApplicationRecordAuthorizationAction.Unknown; try { action = (ApplicationRecordAuthorizationAction)Enum.Parse( typeof(ApplicationRecordAuthorizationAction), tokenNav.GetAttribute("app-record-auth-action", String.Empty)); } catch (ArgumentException) { } createAuthTokenResult.ApplicationId = applicationId; createAuthTokenResult.Status = AuthenticationTokenCreationStatus.Success; createAuthTokenResult.AuthenticationToken = tokenNav.Value; createAuthTokenResult.ApplicationRecordAuthorizationAction = action; } }
/// <summary> /// Extracts the absence reasons from the response XML. /// </summary> /// private void GetAbsenceReasons( CreateAuthenticationTokenResult createAuthTokenResult, XPathNavigator nav) { XPathExpression absenceReasonPath = GetAbsenceReasonXPath(nav); XPathNodeIterator navTokenIterator = nav.Select(absenceReasonPath); GetAbsenceReasonByParseResponse( navTokenIterator, createAuthTokenResult); }
/// <summary> /// Inserts a dictionary of authentication results. /// </summary> /// /// <param name="result"> /// The authentication result. /// </param> /// internal virtual void UpdateAuthenticationResults( CreateAuthenticationTokenResult result) { AddAuthenticationResult(result); }
/// <summary> /// Gets absence reasons regarding why there are no auth tokens /// from the response XML. /// </summary> /// /// <param name="navTokenIterator"> /// The path to the token or tokens. /// </param> /// /// <param name="createAuthTokenResult"> /// The token results. /// </param> /// private static void GetAbsenceReasonByParseResponse( XPathNodeIterator navTokenIterator, CreateAuthenticationTokenResult createAuthTokenResult) { foreach (XPathNavigator tokenNav in navTokenIterator) { Guid applicationId = new Guid(tokenNav.GetAttribute("app-id", String.Empty)); try { createAuthTokenResult.Status = (AuthenticationTokenCreationStatus)Enum.Parse( typeof(AuthenticationTokenCreationStatus), tokenNav.Value); } catch (ArgumentException) { createAuthTokenResult.Status = AuthenticationTokenCreationStatus.Unknown; } createAuthTokenResult.ApplicationId = applicationId; createAuthTokenResult.AuthenticationToken = null; } }
/// <summary> /// Gets authentication token absence reasons from response XML. /// </summary> /// /// <param name="nav"> /// The response XML path navigator. /// </param> /// /// <returns> /// The dictionary of updated authentication results. /// </returns> /// internal CreateAuthenticationTokenResult GetAuthTokenAndAbsenceReasons( XPathNavigator nav) { CreateAuthenticationTokenResult createAuthTokenResult = new CreateAuthenticationTokenResult(); GetAuthenticationToken(createAuthTokenResult, nav); if (createAuthTokenResult.AuthenticationToken == null) { GetStsPayload(createAuthTokenResult, nav); } if (createAuthTokenResult.AuthenticationToken == null && createAuthTokenResult.StsTokenPayload == null) { GetAbsenceReasons(createAuthTokenResult, nav); } return createAuthTokenResult; }
/// <summary> /// Inserts a new authentication result into the authentication results /// dictionary. /// </summary> /// /// <param name="result"> /// The authentication result to add to the results for the specified /// application. /// </param> /// internal virtual void AddAuthenticationResult( CreateAuthenticationTokenResult result) { if (_authResults == null) { _authResults = new Dictionary<Guid, CreateAuthenticationTokenResult>(); } if (_authResults.ContainsKey(result.ApplicationId)) { _authResults.Remove(result.ApplicationId); } _authResults.Add(result.ApplicationId, result); }
/// <summary> /// Extracts the STS payload. /// </summary> /// private void GetStsPayload( CreateAuthenticationTokenResult createAuthTokenResult, XPathNavigator nav) { XPathExpression stsPayloadPath = GetStsPayloadPath(nav); XPathNavigator stsNav = nav.SelectSingleNode(stsPayloadPath); if (stsNav != null) { Guid applicationId = new Guid(stsNav.GetAttribute("app-id", String.Empty)); ApplicationRecordAuthorizationAction action = ApplicationRecordAuthorizationAction.Unknown; try { action = (ApplicationRecordAuthorizationAction)Enum.Parse( typeof(ApplicationRecordAuthorizationAction), stsNav.GetAttribute("app-record-auth-action", String.Empty)); } catch (ArgumentException) { } createAuthTokenResult.StsTokenPayload = stsNav.Value; createAuthTokenResult.ApplicationId = applicationId; createAuthTokenResult.ApplicationRecordAuthorizationAction = action; createAuthTokenResult.Status = AuthenticationTokenCreationStatus.Success; } }
/// <summary> /// Gets the cached authentication keyset pair for the application id. /// </summary> /// /// <param name="applicationId"></param> /// <param name="refreshCounter"></param> /// <param name="keySet"></param> /// <param name="result"></param> /// private static bool GetAuthTokenPair( Guid applicationId, out Int64 refreshCounter, out AuthenticatedSessionKeySet keySet, out CreateAuthenticationTokenResult result) { keySet = null; result = null; refreshCounter = 0; if (_liveKeySetPairs == null) { return false; } AuthenticationTokenKeySetPair pair = _liveKeySetPairs.GetPair(applicationId); if (pair == null) { // create a new unauthenticated pair so that we at least // have the KeySet pair = _liveKeySetPairs.CreatePair(applicationId); keySet = pair.KeySet.Clone(); return false; } lock(pair) { if (!pair.IsAuthenticated()) { keySet = pair.KeySet.Clone(); return false; } refreshCounter = pair.RefreshCounter; keySet = pair.KeySet.Clone(); result = pair.AuthenticationResult; return true; } }
/// <summary> /// Inserts a dictionary of authentication results. /// </summary> /// /// <remarks> /// This may be called from two primary code paths: /// /// 1) WebApplicationCredential.AuthenticateKeySetPair /// pair is already locked by calling thread. /// 2) and CreateAuthenticatedSessionToken /// a) the credential could be totally unintialized, including the /// static credentials, so there will not be a lock on the pair. /// But it doesn't matter since there are no contending threads /// to grab the pair during this call. The lock call is a slight /// overhead in this very rare case. /// b) the credential already has an existing token, including /// the static credentials. This call will update the credentials /// so it's possible the pair is being used by another thread. /// /// This method only update results for the application id for the web /// app. /// </remarks> /// /// <param name="result"> /// The result of the authentication request. /// </param> /// internal override void UpdateAuthenticationResults( CreateAuthenticationTokenResult result) { if (result.ApplicationId == ApplicationId) { if (CreateAuthenticationTokenResult.IsAuthenticated(result)) { AuthenticationTokenKeySetPair pair = _liveKeySetPairs.GetPair(ApplicationId); if (pair == null) { // this should only be true for a call to // CreateAuthenticatedSessionToken on an // unitialized WebApplicationCredential state - // both static and instance. pair = _liveKeySetPairs.CreatePair(ApplicationId); } lock(pair) { // update the static keyset pair pair.KeySet = KeySet.Clone(); pair.Update(result); } // update the instance with the authentication info LoadAuthTokenPair(ApplicationId); } } }