563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste/*
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * The contents of this file are subject to the terms of the Common Development and
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Distribution License (the License). You may not use this file except in compliance with the
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * License.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * specific language governing permission and limitations under the License.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * When distributing Covered Software, include this CDDL Header Notice in each file and include
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Header, with the fields enclosed by brackets [] replaced by your own identifying
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * information: "Portions copyright [year] [name of copyright owner]".
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Copyright 2015 ForgeRock AS.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste */
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joostepackage com.sun.identity.authentication.audit;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static com.sun.identity.authentication.util.ISAuthConstants.SHARED_STATE_USERNAME;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static java.util.Collections.emptyMap;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.audit.events.AuthenticationAuditEventBuilder.Status.*;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.AUTHENTICATION_TOPIC;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.Component.AUTHENTICATION;
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.EntriesInfoFieldKey.AUTH_CONTROL_FLAG;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.EventName.AM_LOGIN_MODULE_COMPLETED;
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.LOGIN_MODULE_CONTROL_FLAG;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.context.AuditRequestContext.getTransactionIdValue;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.utils.StringUtils.isEmpty;
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Joosteimport static org.forgerock.openam.utils.StringUtils.isNotEmpty;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport com.sun.identity.authentication.service.LoginState;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.audit.events.AuthenticationAuditEventBuilder.Status;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AMAuthenticationAuditEventBuilder;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AuditEventFactory;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AuditEventPublisher;
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Joosteimport org.forgerock.openam.audit.context.AuditRequestContext;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.model.AuthenticationAuditEntry;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport javax.inject.Inject;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport java.security.Principal;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport java.util.Map;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste/**
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * This auditor is specifically aimed at constructing and logging authentication events for login modules.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @since 13.0.0
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste */
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joostepublic class AuthenticationModuleEventAuditor extends AbstractAuthenticationEventAuditor {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste /**
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Constructor for {@link AuthenticationModuleEventAuditor}.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param eventPublisher The publisher responsible for logging the events.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param eventFactory The factory that can be used to create the events.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste */
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste @Inject
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste public AuthenticationModuleEventAuditor(AuditEventPublisher eventPublisher, AuditEventFactory eventFactory) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste super(eventPublisher, eventFactory);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste /**
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Log an authentication module successful completion event.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param loginState The login state object.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param principal The principal for this module.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param auditEntryDetail A map containing audit entry details.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste */
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste public void auditModuleSuccess(LoginState loginState, Principal principal,
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste AuthenticationAuditEntry auditEntryDetail) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String realm = getRealmFromState(loginState);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
dfa51161ad226f5998270e3becb25817774aa168Tony Bamford if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC, AM_LOGIN_MODULE_COMPLETED)) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String principalName = principal == null ? null : principal.getName();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String authId = getUserId(principalName, realm);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste auditModuleEvent(loginState, realm, principalName, authId, SUCCESSFUL, auditEntryDetail);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste /**
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Log an authentication module failure completion event.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste *
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param loginState The login state object.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param principal The principal for this module.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param auditEntryDetail A map containing audit entry details.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste */
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste public void auditModuleFailure(LoginState loginState, Principal principal,
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste AuthenticationAuditEntry auditEntryDetail) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String realm = getRealmFromState(loginState);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
dfa51161ad226f5998270e3becb25817774aa168Tony Bamford if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC, AM_LOGIN_MODULE_COMPLETED)) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String principalName = principal == null ? null : principal.getName();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste Map sharedState = loginState == null ? emptyMap() : loginState.getSharedState();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String authId = getUserId(principalName, realm);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste if ((isEmpty(principalName) || isEmpty(authId)) && sharedState.containsKey(SHARED_STATE_USERNAME)) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste principalName = (String) sharedState.get(SHARED_STATE_USERNAME);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste authId = getUserId(principalName, realm);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste auditModuleEvent(loginState, realm, principalName, authId, FAILED, auditEntryDetail);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
a805ad8fd997c440021b625583752605188e4de3Brian Bailey private void auditModuleEvent(LoginState loginState, String realm, String principal, String userId,
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste Status result, AuthenticationAuditEntry auditEntryDetail) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Jooste String controlFlag = AuditRequestContext.getProperty(LOGIN_MODULE_CONTROL_FLAG);
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Jooste if (auditEntryDetail != null && isNotEmpty(controlFlag)) {
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Jooste auditEntryDetail.addInfo(AUTH_CONTROL_FLAG, controlFlag);
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Jooste }
deab5d0e23a609e0eb9c5915e6cd0f4e26aac38fJaco Jooste
c1218d78f656be3cbe77704bc80bb83b82fdc277Jaco Jooste AMAuthenticationAuditEventBuilder builder = eventFactory.authenticationEvent(realm)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .transactionId(getTransactionIdValue())
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .component(AUTHENTICATION)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .eventName(AM_LOGIN_MODULE_COMPLETED)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .result(result)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .entry(auditEntryDetail)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .trackingIds(getTrackingIds(loginState))
a805ad8fd997c440021b625583752605188e4de3Brian Bailey .userId(userId)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .principal(principal);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste }
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste}