public static void PerformAuditSuccessActions(LapRequestModel model, TargetElement target, ReaderElement reader, UserPrincipal user, ComputerPrincipal computer, SearchResult searchResult) { Dictionary <string, string> tokens = BuildTokenDictionary(target, reader, user, computer, searchResult, model.ComputerName); string logSuccessMessage = Reporting.LogSuccessTemplate ?? LogMessages.DefaultAuditSuccessText; string emailSuccessMessage = Reporting.EmailSuccessTemplate ?? $"<html><head/><body><pre>{LogMessages.DefaultAuditSuccessText}</pre></body></html>"; LogEventInfo logEvent = new LogEventInfo(LogLevel.Info, Reporting.Logger.Name, ReplaceTokens(tokens, logSuccessMessage, false)); logEvent.Properties.Add("EventID", EventIDs.PasswordAccessed); Reporting.Logger.Log(logEvent); try { ICollection <string> recipients = Reporting.BuildRecipientList(target, reader, true, user); if (recipients.Count > 0) { string subject = ReplaceTokens(tokens, LogMessages.AuditEmailSubjectSuccess, false); Reporting.SendEmail(recipients, subject, ReplaceTokens(tokens, emailSuccessMessage, true)); } } catch (Exception iex) { Reporting.LogErrorEvent(EventIDs.AuditErrorCannotSendSuccessEmail, "An error occurred sending the success audit email", iex); } }
private static ICollection <string> BuildRecipientList(TargetElement target, ReaderElement reader, bool success, UserPrincipal user = null) { HashSet <string> list = new HashSet <string>(StringComparer.CurrentCultureIgnoreCase); if ((success && (target?.Audit?.NotifySuccess ?? false)) || (!success && (target?.Audit?.NotifyFailure ?? false))) { Reporting.SplitRecipientsAndAddtoList(target?.Audit?.EmailAddresses, list); } if ((success && (reader?.Audit?.NotifySuccess ?? false)) || (!success && (reader?.Audit?.NotifyFailure ?? false))) { Reporting.SplitRecipientsAndAddtoList(reader?.Audit?.EmailAddresses, list); } if ((success && (LapsConfigSection.Configuration?.Audit?.NotifySuccess ?? false)) || (!success && (LapsConfigSection.Configuration?.Audit?.NotifyFailure ?? false))) { Reporting.SplitRecipientsAndAddtoList(LapsConfigSection.Configuration?.Audit?.EmailAddresses, list); } if (list.Remove("{user.EmailAddress}")) { if (!string.IsNullOrWhiteSpace(user?.EmailAddress)) { list.Add(user.EmailAddress); } } return(list); }
private static void SendEmail(IEnumerable <string> recipients, string subject, string body) { if (!Reporting.IsSmtpConfigured()) { Logger.Trace("SMTP is not configured, discarding mail message"); return; } using (SmtpClient client = new SmtpClient()) { using (MailMessage message = new MailMessage()) { foreach (string recipient in recipients) { message.To.Add(recipient); } if (message.To.Count == 0) { Reporting.Logger.Trace($"Not sending notification email because there are no recipients"); return; } message.IsBodyHtml = true; message.Subject = subject; message.Body = body; client.Send(message); } } }
private static Task HandleAuthNFailed <TMessage, TOptions>(AuthenticationFailedNotification <TMessage, TOptions> context) { Reporting.LogErrorEvent(EventIDs.OwinAuthNError, LogMessages.AuthNProviderError, context.Exception); context.HandleResponse(); context.Response.Redirect($"/Home/AuthNError?message={HttpUtility.UrlEncode(context.Exception?.Message ?? "Unknown error")}"); return(Task.FromResult(0)); }
private static bool IsUserThresholdExceeded(LapRequestModel model, UserPrincipal p, HttpRequestBase r, int threshold, int duration) { if (RateLimiter.IsThresholdExceeded(p, threshold, duration)) { Reporting.PerformAuditFailureActions(model, UIMessages.RateLimitError, EventIDs.RateLimitExceededUser, string.Format(LogMessages.RateLimitExceededUser, p.SamAccountName, r.UserHostAddress, threshold, duration), null, null, null, p, null); return(true); } return(false); }
private static Task FindClaimIdentityInDirectoryOrFail <TMessage, TOptions>(SecurityTokenValidatedNotification <TMessage, TOptions> context) { ClaimsIdentity user = context.AuthenticationTicket.Identity; string sid = user.FindUserPrincipalByClaim(Startup.ClaimType, Startup.ClaimName)?.Sid?.Value; if (sid == null) { string message = string.Format(LogMessages.UserNotFoundInDirectory, user.ToClaimList()); Reporting.LogErrorEvent(EventIDs.SsoIdentityNotFound, message, null); context.HandleResponse(); context.Response.Redirect($"/Home/AuthNError?message={HttpUtility.UrlEncode(UIMessages.SsoIdentityNotFound)}"); return(Task.CompletedTask); } user.AddClaim(new Claim(ClaimTypes.PrimarySid, sid)); Reporting.LogSuccessEvent(EventIDs.UserAuthenticated, string.Format(LogMessages.AuthenticatedAndMappedUser, user.ToClaimList())); return(Task.CompletedTask); }
public static void PerformAuditFailureActions(LapRequestModel model, string userMessage, int eventID, string logMessage, Exception ex, TargetElement target, ReaderElement reader, UserPrincipal user, ComputerPrincipal computer) { Dictionary <string, string> tokens = BuildTokenDictionary(target, reader, user, computer, null, model.ComputerName, logMessage ?? userMessage); string logFailureMessage = Reporting.LogFailureTemplate ?? LogMessages.DefaultAuditFailureText; string emailFailureMessage = Reporting.EmailFailureTemplate ?? $"<html><head/><body><pre>{LogMessages.DefaultAuditFailureText}</pre></body></html>"; Reporting.LogErrorEvent(eventID, ReplaceTokens(tokens, logFailureMessage, false), ex); try { ICollection <string> recipients = Reporting.BuildRecipientList(target, reader, false); if (recipients.Count > 0) { string subject = ReplaceTokens(tokens, LogMessages.AuditEmailSubjectFailure, false); Reporting.SendEmail(recipients, subject, ReplaceTokens(tokens, emailFailureMessage, true)); } } catch (Exception iex) { Reporting.LogErrorEvent(EventIDs.AuditErrorCannotSendFailureEmail, "An error occurred sending the failure audit email", iex); } }
public void ConfigureOpenIDConnect(IAppBuilder app) { Startup.CanLogout = true; Startup.ClaimName = ConfigurationManager.AppSettings["oidc:claimName"] ?? ClaimTypes.Upn; if (Enum.TryParse(ConfigurationManager.AppSettings["oidc:claimType"], out IdentityType claimType)) { Startup.ClaimType = claimType; } else { Startup.ClaimType = IdentityType.UserPrincipalName; } AntiForgeryConfig.UniqueClaimTypeIdentifier = ConfigurationManager.AppSettings["oidc:uniqueClaimTypeIdentifier"] ?? ClaimTypes.PrimarySid; string responseType = ConfigurationManager.AppSettings["oidc:responseType"] ?? OpenIdConnectResponseType.IdToken; app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieManager = new SystemWebCookieManager(), AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = this.clientId, ClientSecret = this.clientSecret, Authority = this.authority, RedirectUri = this.redirectUri, ResponseType = responseType, Scope = OpenIdConnectScope.OpenIdProfile, PostLogoutRedirectUri = this.postLogoutRedirectUri ?? new Uri(new Uri(this.redirectUri.Trim('/', '\\')), "Home/LogOut").ToString(), TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", SaveSigninToken = true }, Notifications = new OpenIdConnectAuthenticationNotifications { AuthorizationCodeReceived = async n => { try { OpenIdConnectConfiguration config = await n.Options.ConfigurationManager.GetConfigurationAsync(n.Request.CallCancelled).ConfigureAwait(false); TokenClient tokenClient = new TokenClient(config.TokenEndpoint, this.clientId, this.clientSecret); TokenResponse tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, this.redirectUri).ConfigureAwait(false); if (tokenResponse.IsError) { throw new Exception(tokenResponse.Error); } UserInfoClient userInfoClient = new UserInfoClient(config.UserInfoEndpoint); UserInfoResponse userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken); List <Claim> claims = new List <Claim>(); claims.AddRange(userInfoResponse.Claims); claims.Add(new Claim("id_token", tokenResponse.IdentityToken)); claims.Add(new Claim("access_token", tokenResponse.AccessToken)); if (!string.IsNullOrEmpty(tokenResponse.RefreshToken)) { claims.Add(new Claim("refresh_token", tokenResponse.RefreshToken)); } n.AuthenticationTicket.Identity.AddClaims(claims); } catch (Exception ex) { Reporting.LogErrorEvent(EventIDs.OidcAuthZCodeError, LogMessages.AuthZCodeFlowError, ex); n.Response.Redirect($"/Home/AuthNError?message={HttpUtility.UrlEncode(ex.Message)}"); } }, SecurityTokenValidated = n => { ClaimsIdentity user = n.AuthenticationTicket.Identity; user.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); return(Startup.FindClaimIdentityInDirectoryOrFail(n)); }, RedirectToIdentityProvider = n => { // If signing out, add the id_token_hint if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout) { Claim idTokenClaim = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenClaim != null) { n.ProtocolMessage.IdTokenHint = idTokenClaim.Value; } } logger.Trace($"Redirecting to IdP for {n.ProtocolMessage.RequestType}"); return(Task.CompletedTask); }, AuthenticationFailed = Startup.HandleAuthNFailed }, }); }