Skip to content

Commit

Permalink
Add debug logging
Browse files Browse the repository at this point in the history
  • Loading branch information
byronantak committed Nov 26, 2024
1 parent e0aaa45 commit 7a3f991
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
public class HeaderPreAuthFilter extends AbstractPreAuthenticatedProcessingFilter {
protected HeaderSecurityConfig headerSecurityConfig;

/** logger */
static Logger logger = LoggerFactory.getLogger(HeaderPreAuthFilter.class);

public HeaderPreAuthFilter(HeaderSecurityConfig headerSecurityConfig) {
Expand All @@ -19,6 +18,7 @@ public HeaderPreAuthFilter(HeaderSecurityConfig headerSecurityConfig) {
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String forwardedUser = request.getHeader(headerSecurityConfig.userIdentifyingHeader);
if (forwardedUser != null) {
logger.debug("Forwarded user: {}", forwardedUser);
if (!forwardedUser.isEmpty()) {
return forwardedUser;
}
Expand All @@ -27,6 +27,7 @@ protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
String forwardedServiceSpiffe =
request.getHeader(headerSecurityConfig.serviceIdentifyingHeader);
if (forwardedServiceSpiffe != null) {
logger.debug("Forwarded service: {}", forwardedServiceSpiffe);
if (!forwardedServiceSpiffe.isEmpty()) {
return forwardedServiceSpiffe;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,46 @@
public class HeaderSecurityConfig {

@Value("${l10n.spring.security.header.user.identifyingHeader:}")
public String userIdentifyingHeader;
protected String userIdentifyingHeader;

@Value("${l10n.spring.security.header.service.identifyingHeader:}")
public String serviceIdentifyingHeader;
protected String serviceIdentifyingHeader;

@Value("${l10n.spring.security.header.service.identifyingPrefix:}")
public String servicePrefix;
protected String servicePrefix;

@Value("${l10n.spring.security.header.service.delimiter:/}")
public String serviceDelimiter;
protected String serviceDelimiter;

public String getUserIdentifyingHeader() {
return userIdentifyingHeader;
}

public void setUserIdentifyingHeader(String userIdentifyingHeader) {
this.userIdentifyingHeader = userIdentifyingHeader;
}

public String getServiceIdentifyingHeader() {
return serviceIdentifyingHeader;
}

public void setServiceIdentifyingHeader(String serviceIdentifyingHeader) {
this.serviceIdentifyingHeader = serviceIdentifyingHeader;
}

public String getServicePrefix() {
return servicePrefix;
}

public void setServicePrefix(String servicePrefix) {
this.servicePrefix = servicePrefix;
}

public String getServiceDelimiter() {
return serviceDelimiter;
}

public void setServiceDelimiter(String serviceDelimiter) {
this.serviceDelimiter = serviceDelimiter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import com.box.l10n.mojito.entity.security.user.User;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

@Component
@ConditionalOnProperty("l10n.spring.security.services.enableFuzzyMatch")
public class ServiceDisambiguator {

static Logger logger = LoggerFactory.getLogger(ServiceDisambiguator.class);

@Autowired HeaderSecurityConfig headerSecurityConfig;

/***
Expand All @@ -21,6 +27,7 @@ public class ServiceDisambiguator {
*/
public User findServiceWithCommonAncestor(List<User> services, String servicePath) {
if (services == null || servicePath == null || services.isEmpty() || servicePath.isEmpty()) {
logger.debug("No services found or no service path given");
return null;
}

Expand All @@ -30,8 +37,10 @@ public User findServiceWithCommonAncestor(List<User> services, String servicePat

for (User currentService : services) {
String currentServicePath = currentService.getUsername();
logger.debug("Evaluating service: {}", currentServicePath);
// Check for exact match first
if (servicePath.equals(currentServicePath)) {
logger.debug("Found exact service: {}", currentServicePath);
return currentService;
}

Expand All @@ -50,6 +59,8 @@ public User findServiceWithCommonAncestor(List<User> services, String servicePat
}
}

logger.debug("Common ancestor between services found: {}", commonAncestor);

// Update the service which shares the shortest path
String mostCommonAncestor = commonAncestor.toString();
if (mostCommonAncestor.isEmpty()) {
Expand All @@ -67,6 +78,9 @@ public User findServiceWithCommonAncestor(List<User> services, String servicePat
}
}

logger.debug(
"Matching ancestor service: {}",
Optional.ofNullable(closestService).map(User::getUsername).orElse("null"));
return closestService;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.box.l10n.mojito.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
Expand All @@ -8,6 +10,9 @@
/** This service handles requests from users and services differently */
public class UserDetailServiceAuthWrapper
implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {

Logger logger = LoggerFactory.getLogger(UserDetailServiceAuthWrapper.class);

protected PrincipalDetailService userDetailsService = null;
protected HeaderSecurityConfig headerSecurityConfig;

Expand All @@ -23,6 +28,8 @@ public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
String username = token.getName();
boolean isService =
headerSecurityConfig != null && username.contains(headerSecurityConfig.servicePrefix);
logger.debug("User identifier: {}", username);
logger.debug("Following service logic: {}", isService);
if (isService) {
return this.userDetailsService.loadServiceWithName(username);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ AND LOWER(:serviceName) LIKE CONCAT(LOWER(u.username), '%')
AND u.enabled IS TRUE
""")
@EntityGraph(value = "User.legacy", type = EntityGraphType.FETCH)
Optional<List<User>> findService(
Optional<List<User>> findServicesByServiceNameAndPrefix(
@Param("serviceName") String serviceName, @Param("servicePrefix") String servicePrefix);
}
Original file line number Diff line number Diff line change
Expand Up @@ -409,20 +409,23 @@ public Page<User> findByUsernameOrName(String username, String search, Pageable
/**
* Gets a service by name and if it doesn't exist create a created user.
*
* <p>All admin service accounts should already be created beforehand however, create a non-admin
* account to so long. If they need admin permissions, we will promote the account
* <p>All admin service accounts should already be created beforehand.
* Get the exact service account or any service account which is the
* ancestor service to the account
*
* @param serviceName
* @return
*/
public User getServiceAccountUser(String serviceName) {
if (serviceDisambiguator == null) {
logger.debug("Service Disambiguator is null. Falling back to regular exact match logic");
return userRepository.findByUsername(serviceName);
}

Optional<List<User>> users =
userRepository.findService(serviceName, headerSecurityConfig.servicePrefix);
userRepository.findServicesByServiceNameAndPrefix(serviceName, headerSecurityConfig.getServicePrefix());
if (users.isEmpty()) {
logger.debug("No matching services found as per DB query");
sendPagerDutyNotification(serviceName);
logger.error(
"Service '{}' attempted and failed authentication. No matching services found.",
Expand All @@ -433,19 +436,22 @@ public User getServiceAccountUser(String serviceName) {
User matchingUser =
serviceDisambiguator.findServiceWithCommonAncestor(users.get(), serviceName);
if (matchingUser == null) {
logger.debug("No matching services found as per ServiceDisambiguator");
sendPagerDutyNotification(serviceName);
logger.error(
"Service '{}' attempted and failed authentication. No services could be fuzzy matched",
serviceName);
throw new UsernameNotFoundException("Service with name '" + serviceName + "' was not found");
}

logger.debug("Matching service found: {}", matchingUser.getUsername());
return matchingUser;
}

private String normalizeServiceName(String serviceName) {
return serviceName
.replaceAll(headerSecurityConfig.servicePrefix, "")
.replaceAll(headerSecurityConfig.serviceDelimiter, ":");
.replaceAll(headerSecurityConfig.getServicePrefix(), "")
.replaceAll(headerSecurityConfig.getServiceDelimiter(), ":");
}

private void sendPagerDutyNotification(String serviceName) {
Expand Down

0 comments on commit 7a3f991

Please sign in to comment.