OPENDJ-2465 Add support for transactionId in current DJ access and HTTP access loggers
1 files added
16 files modified
| | |
| | | ! CDDL HEADER END |
| | | ! |
| | | ! |
| | | ! Copyright 2013 ForgeRock AS |
| | | ! Copyright 2013-2015 ForgeRock AS |
| | | ! --> |
| | | <adm:managed-object name="file-based-http-access-log-publisher" |
| | | plural-name="file-based-http-access-log-publishers" |
| | |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>cs-host c-ip cs-username x-datetime cs-method cs-uri-query |
| | | cs-version sc-status cs(User-Agent) x-connection-id x-etime</adm:value> |
| | | cs-version sc-status cs(User-Agent) x-connection-id x-etime x-transaction-id</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | |
| | | date and time for the logged HTTP request and its ouput is |
| | | controlled by the "ds-cfg-log-record-time-format" property, |
| | | "x-etime" displays the total execution time for the logged HTTP |
| | | request. |
| | | request, "x-transaction-id" displays the transaction id associated |
| | | to a request |
| | | </adm:synopsis> |
| | | </adm:pattern> |
| | | </adm:string> |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="trust-transaction-ids" advanced="true"> |
| | | <adm:synopsis> |
| | | Indicates whether the directory server should trust the |
| | | transaction ids that may be received from requests, either |
| | | through a LDAP control or through a HTTP header. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>false</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:boolean /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:name>ds-cfg-trust-transaction-ids</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| | |
| | | <groupId>org.forgerock.commons</groupId> |
| | | <artifactId>forgerock-audit-json</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.forgerock.commons</groupId> |
| | | <artifactId>forgerock-audit-handler-syslog</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- servlet and mail --> |
| | | <dependency> |
| | |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.155 |
| | | NAME 'ds-cfg-trust-transaction-ids' |
| | | EQUALITY booleanMatch |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.1 |
| | | NAME 'ds-cfg-access-control-handler' |
| | | SUP top |
| | |
| | | ds-cfg-etime-resolution $ |
| | | ds-cfg-max-allowed-client-connections $ |
| | | ds-cfg-max-psearches $ |
| | | ds-cfg-max-internal-buffer-size ) |
| | | ds-cfg-max-internal-buffer-size $ |
| | | ds-cfg-trust-transaction-ids) |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.40 |
| | | NAME 'ds-cfg-root-dn-user' |
| | |
| | | import org.opends.server.admin.std.server.GlobalCfg; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | | import org.opends.server.api.AuthenticationPolicy; |
| | | import org.opends.server.loggers.CommonAudit; |
| | | import org.opends.server.schema.SchemaUpdater; |
| | | import org.opends.server.types.*; |
| | | |
| | |
| | | setMaxPersistentSearchLimit(globalConfig.getMaxPsearches()); |
| | | setMaxInternalBufferSize((int) globalConfig.getMaxInternalBufferSize()); |
| | | |
| | | // For tools, common audit may not be available |
| | | CommonAudit commonAudit = serverContext.getCommonAudit(); |
| | | if (commonAudit != null) |
| | | { |
| | | commonAudit.setTrustTransactionIds(globalConfig.isTrustTransactionIds()); |
| | | } |
| | | |
| | | // Update the "new" schema with configuration changes |
| | | SchemaUpdater schemaUpdater = serverContext.getSchemaUpdater(); |
| | | SchemaBuilder schemaBuilder = schemaUpdater.getSchemaBuilder(); |
| | |
| | | |
| | | initializeSchema(); |
| | | |
| | | commonAudit = new CommonAudit(); |
| | | |
| | | // Allow internal plugins to be registered. |
| | | pluginConfigManager.initializePluginConfigManager(); |
| | | |
| | |
| | | retentionPolicyConfigManager = new LogRetentionPolicyConfigManager(serverContext); |
| | | retentionPolicyConfigManager.initializeLogRetentionPolicyConfig(); |
| | | |
| | | commonAudit = new CommonAudit(); |
| | | loggerConfigManager = new LoggerConfigManager(serverContext); |
| | | loggerConfigManager.initializeLoggerConfig(); |
| | | |
| | |
| | | */ |
| | | package org.opends.server.loggers; |
| | | |
| | | import static java.util.Arrays.asList; |
| | | |
| | | import static org.opends.messages.LoggerMessages.*; |
| | | import static java.util.Collections.newSetFromMap; |
| | | import static org.forgerock.audit.AuditServiceBuilder.newAuditService; |
| | |
| | | import java.io.InputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | import java.util.regex.Pattern; |
| | | |
| | | import org.forgerock.audit.AuditException; |
| | |
| | | import org.forgerock.audit.events.EventTopicsMetaData; |
| | | import org.forgerock.audit.events.handlers.FileBasedEventHandlerConfiguration.FileRetention; |
| | | import org.forgerock.audit.events.handlers.FileBasedEventHandlerConfiguration.FileRotation; |
| | | import org.forgerock.audit.filter.FilterPolicy; |
| | | import org.forgerock.audit.handlers.csv.CsvAuditEventHandler; |
| | | import org.forgerock.audit.handlers.csv.CsvAuditEventHandlerConfiguration; |
| | | import org.forgerock.audit.handlers.csv.CsvAuditEventHandlerConfiguration.CsvFormatting; |
| | |
| | | */ |
| | | public class CommonAudit |
| | | { |
| | | /** Transaction id used when the incoming request does not contain a transaction id. */ |
| | | public static final String DEFAULT_TRANSACTION_ID = "0"; |
| | | |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | /** Audit service shared by all HTTP access publishers. */ |
| | | private final AuditServiceProxy httpAccessAuditService; |
| | | |
| | | private final AtomicBoolean trustTransactionIds = new AtomicBoolean(false); |
| | | |
| | | /** |
| | | * Creates the common audit. |
| | |
| | | this.httpAccessAuditService = createAuditServiceWithoutHandlers(); |
| | | } |
| | | |
| | | /** |
| | | * Indicates if transactionIds received from requests should be trusted. |
| | | * |
| | | * @return {@code true} if transactionIds should be trusted, {@code false} otherwise |
| | | */ |
| | | public boolean shouldTrustTransactionIds() |
| | | { |
| | | return trustTransactionIds.get(); |
| | | } |
| | | |
| | | /** |
| | | * Sets the indicator for transactionIds trusting. |
| | | * |
| | | * @param shouldTrust |
| | | * {@code true} if transactionIds should be trusted, {@code false} |
| | | * otherwise |
| | | */ |
| | | public void setTrustTransactionIds(boolean shouldTrust) |
| | | { |
| | | trustTransactionIds.set(shouldTrust); |
| | | } |
| | | |
| | | private AuditServiceProxy createAuditServiceWithoutHandlers() throws ConfigException |
| | | { |
| | | try |
| | |
| | | |
| | | AuditServiceConfiguration auditConfig = new AuditServiceConfiguration(); |
| | | auditConfig.setAvailableAuditEventHandlers(setup.getHandlerNames()); |
| | | auditConfig.setFilterPolicies(getFilterPoliciesToPreventHttpHeadersLogging()); |
| | | builder.withConfiguration(auditConfig); |
| | | AuditService audit = builder.build(); |
| | | |
| | |
| | | return proxy; |
| | | } |
| | | |
| | | /** |
| | | * Build filter policies at the AuditService level to prevent logging of the headers for HTTP requests. |
| | | * <p> |
| | | * HTTP Headers may contains authentication information. |
| | | */ |
| | | private Map<String, FilterPolicy> getFilterPoliciesToPreventHttpHeadersLogging() |
| | | { |
| | | Map<String, FilterPolicy> filterPolicies = new HashMap<>(); |
| | | FilterPolicy policy = new FilterPolicy(); |
| | | policy.setExcludeIf(asList("/http-access/http/request/headers")); |
| | | filterPolicies.put("field", policy); |
| | | return filterPolicies; |
| | | } |
| | | |
| | | private void addHandlerToBuilder(PublisherConfig publisher, AuditServiceBuilder builder) throws ConfigException |
| | | { |
| | | if (publisher.isCsv()) |
| | |
| | | import static org.forgerock.json.JsonValue.json; |
| | | import static org.forgerock.json.resource.Requests.newCreateRequest; |
| | | import static org.forgerock.json.resource.ResourcePath.resourcePath; |
| | | import static org.opends.server.loggers.CommonAudit.DEFAULT_TRANSACTION_ID; |
| | | import static org.opends.server.loggers.OpenDJAccessAuditEventBuilder.openDJAccessEvent; |
| | | import static org.opends.server.types.AuthenticationType.SASL; |
| | | |
| | |
| | | import org.opends.server.core.ServerContext; |
| | | import org.opends.server.core.UnbindOperation; |
| | | import org.opends.server.types.AuthenticationInfo; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.DisconnectReason; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.Operation; |
| | | import org.opends.server.util.ServerConstants; |
| | | import org.opends.server.util.StaticUtils; |
| | | |
| | | /** |
| | |
| | | |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | /** Transaction id used when the incoming request does not contain a transaction id. */ |
| | | private static final String DEFAULT_TRANSACTION_ID = "0"; |
| | | |
| | | /** Audit service handler. */ |
| | | private RequestHandler requestHandler; |
| | | |
| | | /** Current configuration for this publisher. */ |
| | | private T config; |
| | | |
| | | private ServerContext serverContext; |
| | | |
| | | @Override |
| | | public void setRequestHandler(RequestHandler handler) |
| | | { |
| | |
| | | public void initializeLogPublisher(final T cfg, ServerContext serverContext) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | this.serverContext = serverContext; |
| | | initializeFilters(cfg); |
| | | config = cfg; |
| | | } |
| | |
| | | .client(clientConnection.getClientAddress(), clientConnection.getClientPort()) |
| | | .server(clientConnection.getServerAddress(), clientConnection.getServerPort()) |
| | | .request(clientConnection.getProtocol(), "CONNECT") |
| | | .transactionId(DEFAULT_TRANSACTION_ID) |
| | | .transactionId(CommonAudit.DEFAULT_TRANSACTION_ID) |
| | | .response(ResponseStatus.SUCCESSFUL, String.valueOf(ResultCode.SUCCESS.intValue()), 0, TimeUnit.MILLISECONDS) |
| | | .ldapConnectionId(clientConnection.getConnectionID()); |
| | | |
| | |
| | | .client(clientConnection.getClientAddress(), clientConnection.getClientPort()) |
| | | .server(clientConnection.getServerAddress(), clientConnection.getServerPort()) |
| | | .request(clientConnection.getProtocol(),"DISCONNECT") |
| | | .transactionId(DEFAULT_TRANSACTION_ID) |
| | | .transactionId(CommonAudit.DEFAULT_TRANSACTION_ID) |
| | | .response(ResponseStatus.SUCCESSFUL, String.valueOf(ResultCode.SUCCESS.intValue()), 0, TimeUnit.MILLISECONDS) |
| | | .ldapConnectionId(clientConnection.getConnectionID()) |
| | | .ldapReason(disconnectReason.toString()) |
| | |
| | | private String getTransactionId(Operation operation) |
| | | { |
| | | String transactionId = getTransactionIdFromControl(operation); |
| | | if (transactionId == null) |
| | | if (transactionId == null || !serverContext.getCommonAudit().shouldTrustTransactionIds()) |
| | | { |
| | | // use a default value because transaction id has no usage in this case |
| | | // use a default value |
| | | transactionId = DEFAULT_TRANSACTION_ID; |
| | | } |
| | | return transactionId; |
| | |
| | | |
| | | private String getTransactionIdFromControl(Operation operation) |
| | | { |
| | | for (Control control : operation.getRequestControls()) |
| | | { |
| | | if (control.getOID().equals(ServerConstants.OID_TRANSACTION_ID_CONTROL)) |
| | | { |
| | | try |
| | | { |
| | | return operation.getRequestControl(TransactionIdControl.DECODER).getTransactionId(); |
| | | TransactionIdControl control = operation.getRequestControl(TransactionIdControl.DECODER); |
| | | return control != null ? control.getTransactionId() : null; |
| | | } |
| | | catch (DirectoryException e) |
| | | { |
| | | logger.error(ERR_COMMON_AUDIT_INVALID_TRANSACTION_ID.get(StaticUtils.stackTraceToSingleLineString(e))); |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS |
| | | * Copyright 2013-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.loggers; |
| | | |
| | |
| | | long getTotalProcessingTime(); |
| | | |
| | | /** |
| | | * Returns the transactionId for this request. |
| | | * |
| | | * @return the transactionId |
| | | */ |
| | | String getTransactionId(); |
| | | |
| | | /** |
| | | * Logs the current request info in the HTTP access log. |
| | | * |
| | | * @param statusCode |
| | |
| | | */ |
| | | package org.opends.server.loggers; |
| | | |
| | | import static org.opends.messages.LoggerMessages.ERR_COMMON_AUDIT_INVALID_TRANSACTION_ID; |
| | | import static org.opends.messages.ConfigMessages.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | |
| | | import org.opends.server.admin.std.server.FileBasedAccessLogPublisherCfg; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.ExtendedOperationHandler; |
| | | import org.opends.server.controls.TransactionIdControl; |
| | | import org.opends.server.core.*; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.opends.server.util.TimeThread; |
| | | |
| | | /** This class provides the implementation of the access logger used by the directory server. */ |
| | |
| | | private boolean isCombinedMode; |
| | | private boolean includeControlOIDs; |
| | | private String timeStampFormat = "dd/MMM/yyyy:HH:mm:ss Z"; |
| | | private ServerContext serverContext; |
| | | |
| | | @Override |
| | | public ConfigChangeResult applyConfigurationChange(FileBasedAccessLogPublisherCfg config) |
| | |
| | | public void initializeLogPublisher(final FileBasedAccessLogPublisherCfg cfg, ServerContext serverContext) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | this.serverContext = serverContext; |
| | | final File logFile = getLogFile(cfg); |
| | | final FileNamingPolicy fnPolicy = new TimeStampNaming(logFile); |
| | | |
| | |
| | | buffer.append(" conn=").append(operation.getConnectionID()); |
| | | buffer.append(" op=").append(operation.getOperationID()); |
| | | buffer.append(" msgID=").append(operation.getMessageID()); |
| | | appendTransactionId(operation, buffer); |
| | | } |
| | | |
| | | private void appendModifyDNRequest(final ModifyDNOperation modifyDNOperation, |
| | |
| | | } |
| | | } |
| | | |
| | | private void appendTransactionId(Operation operation, final StringBuilder buffer) |
| | | { |
| | | // In test context, serverContext may be null |
| | | if (serverContext != null && serverContext.getCommonAudit().shouldTrustTransactionIds()) |
| | | { |
| | | String transactionId = getTransactionIdFromControl(operation); |
| | | if (transactionId != null) |
| | | { |
| | | buffer.append(" transactionId=").append(transactionId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private String getTransactionIdFromControl(Operation operation) |
| | | { |
| | | try |
| | | { |
| | | TransactionIdControl control = operation.getRequestControl(TransactionIdControl.DECODER); |
| | | return control != null ? control.getTransactionId() : null; |
| | | } |
| | | catch (DirectoryException e) |
| | | { |
| | | logger.error(ERR_COMMON_AUDIT_INVALID_TRANSACTION_ID.get(StaticUtils.stackTraceToSingleLineString(e))); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private void appendRequestControls(final Operation operation, final StringBuilder buffer) |
| | | { |
| | | appendControls(buffer, " requestControls=", operation.getRequestControls()); |
| | |
| | | private static final String X_CONNECTION_ID = "x-connection-id"; |
| | | private static final String X_DATETIME = "x-datetime"; |
| | | private static final String X_ETIME = "x-etime"; |
| | | private static final String X_TRANSACTION_ID = "x-transaction-id"; |
| | | |
| | | private static final Set<String> ALL_SUPPORTED_FIELDS = new HashSet<>( |
| | | Arrays.asList(ELF_C_IP, ELF_C_PORT, ELF_CS_HOST, ELF_CS_METHOD, |
| | | ELF_CS_URI_QUERY, ELF_CS_USER_AGENT, ELF_CS_USERNAME, ELF_CS_VERSION, |
| | | ELF_S_COMPUTERNAME, ELF_S_IP, ELF_S_PORT, ELF_SC_STATUS, |
| | | X_CONNECTION_ID, X_DATETIME, X_ETIME)); |
| | | X_CONNECTION_ID, X_DATETIME, X_ETIME, X_TRANSACTION_ID)); |
| | | |
| | | /** |
| | | * Returns an instance of the text HTTP access log publisher that will print |
| | |
| | | fields.put(X_CONNECTION_ID, ri.getConnectionID()); |
| | | fields.put(X_DATETIME, TimeThread.getUserDefinedTime(timeStampFormat)); |
| | | fields.put(X_ETIME, ri.getTotalProcessingTime()); |
| | | fields.put(X_TRANSACTION_ID, ri.getTransactionId()); |
| | | |
| | | writeLogRecord(fields, logFormatFields); |
| | | } |
| | |
| | | import org.forgerock.util.promise.Promise; |
| | | import org.forgerock.util.promise.Promises; |
| | | import org.opends.server.admin.std.server.ConnectionHandlerCfg; |
| | | import org.opends.server.core.ServerContext; |
| | | import org.opends.server.schema.SchemaConstants; |
| | | import org.opends.server.types.DisconnectReason; |
| | | import org.opends.server.util.Base64; |
| | |
| | | */ |
| | | private final HTTPAuthenticationConfig authConfig; |
| | | |
| | | private final ServerContext serverContext; |
| | | |
| | | /** |
| | | * Constructs a new instance of this class. |
| | | * |
| | | * @param serverContext |
| | | * The server context. |
| | | * @param connectionHandler |
| | | * the connection handler that accepted this connection |
| | | * @param authenticationConfig |
| | | * configures how to perform the search for the username prior to |
| | | * authentication |
| | | */ |
| | | public CollectClientConnectionsFilter( |
| | | HTTPConnectionHandler connectionHandler, HTTPAuthenticationConfig authenticationConfig) |
| | | public CollectClientConnectionsFilter(ServerContext serverContext, HTTPConnectionHandler connectionHandler, |
| | | HTTPAuthenticationConfig authenticationConfig) |
| | | { |
| | | this.serverContext = serverContext; |
| | | this.connectionHandler = connectionHandler; |
| | | this.authConfig = authenticationConfig; |
| | | } |
| | |
| | | @Override |
| | | public Promise<Response, NeverThrowsException> filter(Context context, Request request, Handler next) |
| | | { |
| | | final HTTPClientConnection clientConnection = new HTTPClientConnection(this.connectionHandler, context, request); |
| | | final HTTPClientConnection clientConnection = |
| | | new HTTPClientConnection(serverContext, this.connectionHandler, context, request); |
| | | connectionHandler.addClientConnection(clientConnection); |
| | | |
| | | if (connectionHandler.keepStats()) |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.protocols.http; |
| | | |
| | | import org.forgerock.http.Filter; |
| | | import org.forgerock.http.Handler; |
| | | import org.forgerock.http.header.MalformedHeaderException; |
| | | import org.forgerock.http.header.TransactionIdHeader; |
| | | import org.forgerock.http.protocol.Headers; |
| | | import org.forgerock.http.protocol.Request; |
| | | import org.forgerock.http.protocol.Response; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.services.TransactionId; |
| | | import org.forgerock.services.context.Context; |
| | | import org.forgerock.services.context.TransactionIdContext; |
| | | import org.forgerock.util.promise.NeverThrowsException; |
| | | import org.forgerock.util.promise.Promise; |
| | | import org.opends.server.core.ServerContext; |
| | | |
| | | /** |
| | | * This filter is responsible for creating a {@link TransactionIdContext} in the |
| | | * context's chain. |
| | | * <p> |
| | | * This class is a copy of org.forgerock.http.filter.TransactionIdInboundFilter |
| | | * in CHF, modified to not use a system property to indicate if transaction id |
| | | * is trusted. Instead, it relies on DJ configuration to allow for runtime |
| | | * modification It would be better if TransactionIdInboundFilter class could be |
| | | * modified to be more generic and then usable by DJ, but it remains to be done. |
| | | */ |
| | | class CommonAuditTransactionIdFilter implements Filter |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | private final ServerContext serverContext; |
| | | |
| | | CommonAuditTransactionIdFilter(ServerContext serverContext) |
| | | { |
| | | this.serverContext = serverContext; |
| | | } |
| | | |
| | | @Override |
| | | public Promise<Response, NeverThrowsException> filter(Context context, Request request, Handler next) |
| | | { |
| | | final TransactionId transactionId = serverContext.getCommonAudit().shouldTrustTransactionIds() ? |
| | | createTransactionId(request.getHeaders()) : new TransactionId(); |
| | | final Context newContext = new TransactionIdContext(context, transactionId); |
| | | return next.handle(newContext, request); |
| | | } |
| | | |
| | | private TransactionId createTransactionId(Headers headers) |
| | | { |
| | | try |
| | | { |
| | | TransactionIdHeader txHeader = headers.get(TransactionIdHeader.class); |
| | | return txHeader == null ? new TransactionId() : txHeader.getTransactionId(); |
| | | } |
| | | catch (MalformedHeaderException ex) |
| | | { |
| | | logger.trace("The TransactionId header is malformed.", ex); |
| | | return new TransactionId(); |
| | | } |
| | | } |
| | | } |
| | |
| | | import static org.forgerock.opendj.adapter.server3x.Converters.getResponseResult; |
| | | import static org.forgerock.opendj.ldap.LdapException.newLdapException; |
| | | import static org.opends.messages.ProtocolMessages.WARN_CLIENT_DISCONNECT_IN_PROGRESS; |
| | | import static org.opends.server.loggers.CommonAudit.DEFAULT_TRANSACTION_ID; |
| | | import static org.opends.server.loggers.AccessLogger.logDisconnect; |
| | | |
| | | import java.net.InetAddress; |
| | |
| | | import java.util.concurrent.atomic.AtomicLong; |
| | | |
| | | import org.forgerock.http.MutableUri; |
| | | import org.forgerock.http.header.MalformedHeaderException; |
| | | import org.forgerock.http.header.TransactionIdHeader; |
| | | import org.forgerock.http.protocol.Request; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | |
| | | import org.opends.server.core.ModifyDNOperation; |
| | | import org.opends.server.core.ModifyOperation; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.core.ServerContext; |
| | | import org.opends.server.loggers.HTTPAccessLogger; |
| | | import org.opends.server.loggers.HTTPRequestInfo; |
| | | import org.opends.server.protocols.ldap.AddResponseProtocolOp; |
| | |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | /** Search Operation with a promise. */ |
| | | private static final class SearchOperationWithPromise extends OperationWithPromise |
| | | { |
| | | |
| | |
| | | /** Security-Strength Factor extracted from the request attribute. */ |
| | | private final int securityStrengthFactor; |
| | | |
| | | /** TransactionId for tracking of ForgeRock stack transactions. */ |
| | | private final String transactionId; |
| | | |
| | | /** |
| | | * Constructs an instance of this class. |
| | | * |
| | | * @param serverContext |
| | | * The server context. |
| | | * @param connectionHandler |
| | | * the connection handler that accepted this connection |
| | | * @param context |
| | | * represents the context of this client connection. |
| | | */ |
| | | public HTTPClientConnection(HTTPConnectionHandler connectionHandler, Context context, Request request) |
| | | public HTTPClientConnection(ServerContext serverContext, HTTPConnectionHandler connectionHandler, Context context, |
| | | Request request) |
| | | { |
| | | this.connectionHandler = connectionHandler; |
| | | final ClientContext clientCtx = context.asContext(ClientContext.class); |
| | |
| | | this.statTracker.updateConnect(); |
| | | this.useNanoTime = DirectoryServer.getUseNanoTime(); |
| | | } |
| | | |
| | | this.transactionId = getTransactionId(serverContext, request); |
| | | this.connectionID = DirectoryServer.newConnectionAccepted(this); |
| | | } |
| | | |
| | | private String getTransactionId(ServerContext serverContext, Request request) |
| | | { |
| | | if (serverContext.getCommonAudit().shouldTrustTransactionIds()) |
| | | { |
| | | try |
| | | { |
| | | TransactionIdHeader txHeader = request.getHeaders().get(TransactionIdHeader.class); |
| | | return txHeader == null ? DEFAULT_TRANSACTION_ID : txHeader.getTransactionId().getValue(); |
| | | } |
| | | catch (MalformedHeaderException e) |
| | | { |
| | | // ignore it |
| | | } |
| | | } |
| | | return DEFAULT_TRANSACTION_ID; |
| | | } |
| | | |
| | | @Override |
| | | public String getAuthUser() |
| | | { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public String getTransactionId() |
| | | { |
| | | return transactionId; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isSecure() |
| | | { |
| | | return isSecure; |
| | |
| | | import org.forgerock.http.Handler; |
| | | import org.forgerock.http.HttpApplication; |
| | | import org.forgerock.http.HttpApplicationException; |
| | | import org.forgerock.http.filter.TransactionIdInboundFilter; |
| | | import org.forgerock.http.handler.Handlers; |
| | | import org.forgerock.http.io.Buffer; |
| | | import org.forgerock.http.protocol.Request; |
| | |
| | | final Object jsonElems = Json.readJsonLenient(new FileReader(configFile)); |
| | | final JsonValue configuration = new JsonValue(jsonElems).recordKeyAccesses(); |
| | | handler = new LdapHttpHandler(configuration); |
| | | filter = new CollectClientConnectionsFilter(connectionHandler, getAuthenticationConfig(configuration)); |
| | | filter = |
| | | new CollectClientConnectionsFilter(serverContext, connectionHandler, getAuthenticationConfig(configuration)); |
| | | configuration.verifyAllKeysAccessed(); |
| | | |
| | | TransactionIdInboundFilter transactionIdFilter = new TransactionIdInboundFilter(); |
| | | RequestHandler requestHandler = serverContext.getCommonAudit().getAuditServiceForHttpAccessLog(); |
| | | CommonAuditTransactionIdFilter transactionIdFilter = new CommonAuditTransactionIdFilter(serverContext); |
| | | CommonAuditHttpAccessAuditFilter httpAccessFilter = |
| | | new CommonAuditHttpAccessAuditFilter(DynamicConstants.PRODUCT_NAME, requestHandler, TimeService.SYSTEM); |
| | | CommonAuditHttpAccessCheckEnabledFilter checkFilter = |
| | |
| | | import org.opends.server.admin.std.server.MonitorProviderCfg; |
| | | import org.opends.server.api.MonitorProvider; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.testng.annotations.Test; |
| | | |
| | | /** This class defines a set of tests for the {@link BackendMonitor} class. */ |
| | | @Test |
| | | public class BackendMonitorTestCase extends GenericMonitorTestCase |
| | | { |
| | | /** |
| | |
| | | */ |
| | | package org.opends.server.protocols.http; |
| | | |
| | | import static org.mockito.Mockito.mock; |
| | | import static org.assertj.core.api.Assertions.*; |
| | | import static org.opends.server.protocols.http.CollectClientConnectionsFilter.*; |
| | | |
| | |
| | | import org.forgerock.http.protocol.Response; |
| | | import org.forgerock.json.resource.ResourceException; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.opends.server.core.ServerContext; |
| | | import org.opends.server.util.Base64; |
| | | import org.testng.annotations.BeforeMethod; |
| | | import org.testng.annotations.DataProvider; |
| | |
| | | private void createConfigAndFilter() |
| | | { |
| | | authConfig = new HTTPAuthenticationConfig(); |
| | | filter = new CollectClientConnectionsFilter(null, authConfig); |
| | | filter = new CollectClientConnectionsFilter(mock(ServerContext.class), null, authConfig); |
| | | } |
| | | |
| | | @DataProvider(name = "Invalid HTTP basic auth strings") |