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 * 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 * 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 * Copyright 2015 ForgeRock AS.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static com.sun.identity.authentication.util.ISAuthConstants.*;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.audit.events.AuthenticationAuditEventBuilder.Status.*;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AMAuditEventBuilderUtils.getTrackingIdFromSSOToken;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.AUTHENTICATION_TOPIC;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.AuthenticationFailureReason.*;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.Component.AUTHENTICATION;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.EntriesInfoFieldKey.*;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.EntriesInfoFieldKey.AUTH_LEVEL;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.AuditConstants.EventName.*;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.audit.context.AuditRequestContext.getTransactionIdValue;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport static org.forgerock.openam.utils.StringUtils.isNotEmpty;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport com.sun.identity.authentication.AuthContext;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport com.sun.identity.authentication.service.AMAuthErrorCode;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport com.sun.identity.authentication.service.LoginState;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AMAuditEventBuilderUtils;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AMAuthenticationAuditEventBuilder;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AuditConstants;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AuditConstants.AuthenticationFailureReason;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AuditEventFactory;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.AuditEventPublisher;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.audit.model.AuthenticationAuditEntry;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport org.forgerock.openam.utils.CollectionUtils;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joosteimport javax.security.auth.callback.NameCallback;
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * This auditor is specifically aimed at constructing and logging authentication events for the login process.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @since 13.0.0
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Joostepublic class AuthenticationProcessEventAuditor extends AbstractAuthenticationEventAuditor {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Constructor for {@link AuthenticationProcessEventAuditor}.
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 public AuthenticationProcessEventAuditor(AuditEventPublisher eventPublisher, AuditEventFactory eventFactory) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Log an authentication process successful completion event.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param loginState The login state object.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste public void auditLoginSuccess(LoginState loginState) {
dfa51161ad226f5998270e3becb25817774aa168Tony Bamford if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC, AM_LOGIN_COMPLETED)) {
c1218d78f656be3cbe77704bc80bb83b82fdc277Jaco Jooste AMAuthenticationAuditEventBuilder builder = eventFactory.authenticationEvent(realm)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .entry(getAuditEntryDetail(moduleName, loginState))
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Log an authentication process failure event.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param loginState The login state object.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste public void auditLoginFailure(LoginState loginState) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste auditLoginFailure(loginState, findFailureReason(loginState));
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Log an authentication process failure event.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param loginState The login state object.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param failureReason The reason for the failure. If {@literal failureReason} is null then the value of
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * {@link LoginState#getErrorCode()} will be mapped to an {@link AuthenticationFailureReason} with
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * {@link AuthenticationFailureReason#LOGIN_FAILED} as default if the value could not be mapped.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste public void auditLoginFailure(LoginState loginState, AuthenticationFailureReason failureReason) {
dfa51161ad226f5998270e3becb25817774aa168Tony Bamford if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC, AM_LOGIN_COMPLETED)) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String principal = getFailedPrincipal(loginState);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String moduleName = loginState == null ? null : loginState.getFailureModuleNames();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste AuthenticationAuditEntry entryDetail = getAuditEntryDetail(moduleName, loginState);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste entryDetail.addInfo(FAILURE_REASON, failureReason.name());
c1218d78f656be3cbe77704bc80bb83b82fdc277Jaco Jooste AMAuthenticationAuditEventBuilder builder = eventFactory.authenticationEvent(realm)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * Log a logout event.
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste * @param token The {@Link SSOToken} of the event.
dfa51161ad226f5998270e3becb25817774aa168Tony Bamford if (eventPublisher.isAuditing(realm, AUTHENTICATION_TOPIC, AM_LOGOUT)) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste Principal principal = token == null ? null : token.getPrincipal();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste principalName = principal == null ? null : DNUtils.DNtoName(principal.getName());
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste AuthenticationAuditEntry entryDetail = new AuthenticationAuditEntry();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste entryDetail.setModuleId(getSSOTokenProperty(token, AUTH_TYPE));
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String trackingId = getTrackingIdFromSSOToken(token);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String userId = AMAuditEventBuilderUtils.getUserId(token);
c1218d78f656be3cbe77704bc80bb83b82fdc277Jaco Jooste AMAuthenticationAuditEventBuilder builder = eventFactory.authenticationEvent(realm)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste .trackingId(trackingId == null ? "" : trackingId)
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste eventPublisher.tryPublish(AUTHENTICATION_TOPIC, builder.toEvent());
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste private AuthenticationAuditEntry getAuditEntryDetail(String moduleName, LoginState loginState) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste AuthenticationAuditEntry entryDetail = new AuthenticationAuditEntry();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste entryDetail.setModuleId(moduleName == null ? "" : moduleName);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste AuthContext.IndexType indexType = loginState.getIndexType();
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste entryDetail.addInfo(AUTH_INDEX, indexType.toString());
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste entryDetail.addInfo(AUTH_LEVEL, String.valueOf(loginState.getAuthLevel()));
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste private String getSSOTokenProperty(SSOToken ssoToken, String name) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste return (ssoToken == null || name == null) ? null : ssoToken.getProperty(name);
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste private String getFailedPrincipal(LoginState loginState) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste if (CollectionUtils.isNotEmpty(loginState.getAllReceivedCallbacks())) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste for (Callback[] cb : loginState.getAllReceivedCallbacks().values()) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste private AuditConstants.AuthenticationFailureReason findFailureReason(LoginState loginState) {
563b922249eadd0562ddea89c52ed308c2d31c0aJaco Jooste String errorCode = loginState == null ? null : loginState.getErrorCode();