/* * Copyright 2020 LinkedIn Corp. Licensed under the BSD 2-Clause License (the "License"). See License in the project root for license information. */ package com.linkedin.kafka.cruisecontrol.servlet.security.trustedproxy; import com.linkedin.kafka.cruisecontrol.servlet.security.DefaultRoleSecurityProvider; import com.linkedin.kafka.cruisecontrol.servlet.security.SecurityUtils; import org.eclipse.jetty.security.UserStore; import org.eclipse.jetty.security.authentication.AuthorizationService; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.component.AbstractLifeCycle; import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.regex.Pattern; /** * This authorization service simply checks the incoming user against a list of configured service names maintained in * a {@link UserStore} and if specified, the remote IP address against a configured pattern. */ public class TrustedProxyAuthorizationService extends AbstractLifeCycle implements AuthorizationService { private final UserStore _adminUserStore; private final Pattern _trustedProxyIpPattern; TrustedProxyAuthorizationService(List<String> userNames, String trustedProxyIpPattern) { _adminUserStore = new UserStore(); userNames.forEach(u -> _adminUserStore.addUser(u, SecurityUtils.NO_CREDENTIAL, new String[] { DefaultRoleSecurityProvider.ADMIN })); if (trustedProxyIpPattern != null) { _trustedProxyIpPattern = Pattern.compile(trustedProxyIpPattern); } else { _trustedProxyIpPattern = null; } } @Override public UserIdentity getUserIdentity(HttpServletRequest request, String name) { // ConfigurableSpnegoAuthenticator may pass names in servicename/host format but we only store the servicename int nameHostSeparatorIndex = name.indexOf('/'); String serviceName = nameHostSeparatorIndex > 0 ? name.substring(0, nameHostSeparatorIndex) : name; UserIdentity serviceIdentity = _adminUserStore.getUserIdentity(serviceName); if (_trustedProxyIpPattern != null) { return _trustedProxyIpPattern.matcher(request.getRemoteAddr()).matches() ? serviceIdentity : null; } else { return serviceIdentity; } } @Override protected void doStart() throws Exception { _adminUserStore.start(); super.doStart(); } @Override protected void doStop() throws Exception { super.doStop(); _adminUserStore.stop(); } }