public void GenerateAuditEvent(AuditableAction action) { Dictionary <string, string> tokens = this.BuildTokenDictionary(action); List <Exception> exceptions = new List <Exception>(); foreach (INotificationChannel channel in this.notificationChannels) { try { channel.ProcessNotification(action, tokens, this.BuildChannelList(action)); } catch (Exception ex) { this.logger.LogEventError(EventIDs.NotificationChannelError, string.Format(LogMessages.NotificationChannelError, channel.Name), ex); exceptions.Add(ex); } } if (exceptions.Count > 0) { AuditLogFailureException ex = new AuditLogFailureException("The audit message could not be delivered to all notification channels", exceptions); if (action.IsSuccess) { throw ex; } else { this.logger.LogEventError(EventIDs.NotificationChannelError, ex.Message, ex); } } this.GenerateAuditEventLog(action, tokens); }
private void GenerateAuditEventLog(AuditableAction action, Dictionary <string, string> tokens) { string message; if (action.IsSuccess) { message = this.templates.GetTemplate("eventlog-success.txt") ?? LogMessages.DefaultAuditSuccessText; } else { message = this.templates.GetTemplate("eventlog-failure.txt") ?? LogMessages.DefaultAuditFailureText; } message = this.ReplaceTokens(tokens, message, false); this.logger.LogEvent(action.EventID, action.IsSuccess ? LogLevel.Information : LogLevel.Error, message, null); }
public override void UpdateAuditableProperties(AuditableAction action = AuditableAction.Insert, long?userId = null) { DeletedAt = action == AuditableAction.Delete ? DateTime.UtcNow : action == AuditableAction.Reactivate ? null : DeletedAt; DeletedBy = action == AuditableAction.Delete ? userId : action == AuditableAction.Reactivate ? null : DeletedBy; base.UpdateAuditableProperties(action, userId); }
private Dictionary <string, string> BuildTokenDictionary(AuditableAction action) { LapsAuthorizationResponse lapsAuthZResponse = action.AuthzResponse as LapsAuthorizationResponse; JitAuthorizationResponse jitAuthZResponse = action.AuthzResponse as JitAuthorizationResponse; Dictionary <string, string> pairs = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase) { { "{user.SamAccountName}", action.User?.SamAccountName }, { "{user.MsDsPrincipalName}", action.User?.MsDsPrincipalName }, { "{user.DisplayName}", action.User?.DisplayName }, { "{user.UserPrincipalName}", action.User?.UserPrincipalName }, { "{user.Sid}", action.User?.Sid?.ToString() }, { "{user.DistinguishedName}", action.User?.DistinguishedName }, { "{user.Description}", action.User?.Description }, { "{user.EmailAddress}", action.User?.EmailAddress }, { "{user.Guid}", action.User?.Guid?.ToString() }, { "{user.GivenName}", action.User?.GivenName }, { "{user.Surname}", action.User?.Surname }, { "{computer.SamAccountName}", action.Computer?.SamAccountName }, { "{computer.MsDsPrincipalName}", action.Computer?.MsDsPrincipalName }, { "{computer.DistinguishedName}", action.Computer?.DistinguishedName }, { "{computer.Description}", action.Computer?.Description }, { "{computer.DisplayName}", action.Computer?.DisplayName }, { "{computer.Guid}", action.Computer?.Guid?.ToString() }, { "{computer.Sid}", action.Computer?.Sid?.ToString() }, { "{request.ComputerName}", action.RequestedComputerName }, { "{request.Reason}", action.RequestReason ?? "(not provided)" }, { "{AuthzResult.NotificationChannels}", string.Join(",", action.AuthzResponse?.NotificationChannels ?? new List <string>()) }, { "{AuthzResult.MatchedRuleDescription}", action.AuthzResponse?.MatchedRuleDescription }, { "{AuthzResult.MatchedRule}", action.AuthzResponse?.MatchedRule }, { "{AuthzResult.ExpireAfter}", (lapsAuthZResponse?.ExpireAfter ?? jitAuthZResponse?.ExpireAfter)?.ToString() }, { "{AuthzResult.ResponseCode}", action.AuthzResponse?.Code.ToString() }, { "{AuthzResult.AccessType}", action.AuthzResponse?.EvaluatedAccess.ToString() }, { "{AuthzResult.AccessTypeDescription}", action.EvaluatedAccess ?? action.AuthzResponse?.EvaluatedAccess.ToDescription() }, { "{AuthZResult.AccessExpiryDate}", action.AccessExpiryDate }, { "{message}", action.Message }, { "{request.IPAddress}", httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString() }, { "{request.Hostname}", this.TryResolveHostName(httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress) }, { "{datetime}", DateTime.Now.ToString(CultureInfo.CurrentCulture) }, { "{datetimeutc}", DateTime.UtcNow.ToString(CultureInfo.CurrentCulture) }, { "{computer.LapsExpiryDate}", action.AccessExpiryDate }, //deprecated }; return(pairs); }
public virtual void UpdateAuditableProperties(AuditableAction action = AuditableAction.Insert, long?userId = null) { UpdatedAt = action != AuditableAction.Delete && action != AuditableAction.Reactivate ? DateTime.UtcNow : UpdatedAt; UpdatedBy = action != AuditableAction.Delete && action != AuditableAction.Reactivate ? userId : UpdatedBy; CreatedAt = action == AuditableAction.Insert ? DateTime.UtcNow : CreatedAt; CreatedBy = action == AuditableAction.Insert ? userId : CreatedBy; }
private IImmutableSet <string> BuildChannelList(AuditableAction action) { HashSet <string> channelsToNotify = new HashSet <string>(); if (action.AuthzResponse != null) { action.AuthzResponse.NotificationChannels?.ForEach(t => channelsToNotify.Add(t)); } if (action.IsSuccess) { this.auditSettings.GlobalNotifications?.OnSuccess?.ForEach(t => channelsToNotify.Add(t)); } else { this.auditSettings.GlobalNotifications?.OnFailure?.ForEach(t => channelsToNotify.Add(t)); } return(channelsToNotify.ToImmutableHashSet()); }
private void LogRateLimitEvent(AccessRequestModel model, IUser user, RateLimitResult rateLimitResult) { AuditableAction action = new AuditableAction { User = user, IsSuccess = false, RequestedComputerName = model.ComputerName, RequestReason = model.UserRequestReason, }; if (rateLimitResult.IsUserRateLimit) { action.EventID = EventIDs.RateLimitExceededUser; action.Message = string.Format(LogMessages.RateLimitExceededUser, user.MsDsPrincipalName, rateLimitResult.IPAddress, rateLimitResult.Threshold, rateLimitResult.Duration); } else { action.EventID = EventIDs.RateLimitExceededIP; action.Message = string.Format(LogMessages.RateLimitExceededIP, user.MsDsPrincipalName, rateLimitResult.IPAddress, rateLimitResult.Threshold, rateLimitResult.Duration); } this.reporting.GenerateAuditEvent(action); }