org.apache.cxf.ext.logging.event.DefaultLogEventMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-rt-features-logging Show documentation
Show all versions of cxf-rt-features-logging Show documentation
Apache CXF Advanced Logging Feature
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.ext.logging.event;
import java.security.AccessController;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.security.auth.Subject;
import org.apache.cxf.binding.Binding;
import org.apache.cxf.configuration.security.AuthorizationPolicy;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.ext.logging.MaskSensitiveHelper;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.cxf.ws.addressing.AddressingProperties;
import org.apache.cxf.ws.addressing.ContextUtils;
public class DefaultLogEventMapper {
public static final String MASKED_HEADER_VALUE = "XXX";
private static final Set DEFAULT_BINARY_CONTENT_MEDIA_TYPES;
static {
Set mediaTypes = new HashSet<>(6);
mediaTypes.add("application/octet-stream");
mediaTypes.add("application/pdf");
mediaTypes.add("image/png");
mediaTypes.add("image/jpeg");
mediaTypes.add("image/gif");
mediaTypes.add("image/bmp");
DEFAULT_BINARY_CONTENT_MEDIA_TYPES = Collections.unmodifiableSet(mediaTypes);
}
private static final String MULTIPART_CONTENT_MEDIA_TYPE = "multipart";
private final Set binaryContentMediaTypes = new HashSet<>(DEFAULT_BINARY_CONTENT_MEDIA_TYPES);
private MaskSensitiveHelper maskSensitiveHelper = new MaskSensitiveHelper();
public void addBinaryContentMediaTypes(String mediaTypes) {
if (mediaTypes != null) {
Collections.addAll(binaryContentMediaTypes, mediaTypes.split(";"));
}
}
public LogEvent map(final Message message) {
return this.map(message, Collections.emptySet());
}
public LogEvent map(final Message message, final Set sensitiveProtocolHeaders) {
final LogEvent event = new LogEvent();
event.setMessageId(getMessageId(message));
event.setExchangeId((String)message.getExchange().get(LogEvent.KEY_EXCHANGE_ID));
event.setType(getEventType(message));
if (!Boolean.TRUE.equals(message.get(Message.DECOUPLED_CHANNEL_MESSAGE))) {
// avoid logging the default responseCode 200 for the decoupled responses
Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
if (responseCode != null) {
event.setResponseCode(responseCode.toString());
}
}
event.setEncoding(safeGet(message, Message.ENCODING));
event.setHttpMethod(safeGet(message, Message.HTTP_REQUEST_METHOD));
event.setContentType(safeGet(message, Message.CONTENT_TYPE));
Map headerMap = getHeaders(message);
if (sensitiveProtocolHeaders != null && !sensitiveProtocolHeaders.isEmpty()) {
maskSensitiveHelper.maskHeaders(headerMap, sensitiveProtocolHeaders);
}
event.setHeaders(headerMap);
event.setAddress(getAddress(message, event));
event.setPrincipal(getPrincipal(message));
event.setBinaryContent(isBinaryContent(message));
event.setMultipartContent(isMultipartContent(message));
setEpInfo(message, event);
return event;
}
private String getPrincipal(Message message) {
String principal = getJAASPrincipal();
if (principal != null) {
return principal;
}
SecurityContext sc = message.get(SecurityContext.class);
if (sc != null && sc.getUserPrincipal() != null) {
return sc.getUserPrincipal().getName();
}
AuthorizationPolicy authPolicy = message.get(AuthorizationPolicy.class);
if (authPolicy != null) {
return authPolicy.getUserName();
}
return null;
}
private String getJAASPrincipal() {
StringBuilder principals = new StringBuilder();
Iterator extends Object> principalIt = getJAASPrincipals();
while (principalIt.hasNext()) {
principals.append(principalIt.next());
if (principalIt.hasNext()) {
principals.append(',');
}
}
if (principals.length() == 0) {
return null;
}
return principals.toString();
}
private Iterator extends Object> getJAASPrincipals() {
Subject subject = Subject.getSubject(AccessController.getContext());
return subject != null && subject.getPrincipals() != null
? subject.getPrincipals().iterator() : Collections.emptyIterator();
}
private Map getHeaders(Message message) {
Map> headers = CastUtils.cast((Map, ?>)message.get(Message.PROTOCOL_HEADERS));
Map result = new HashMap<>();
if (headers == null) {
return result;
}
for (Map.Entry> entry : headers.entrySet()) {
List