This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch
2269-support-basic-auth-for-prometheus-monitoring-endpoint
in repository https://gitbox.apache.org/repos/asf/streampipes.git
The following commit(s) were added to
refs/heads/2269-support-basic-auth-for-prometheus-monitoring-endpoint by this
push:
new 021b7f511 feat(#2269): Add basic auth to prometheus monitoring endpoint
021b7f511 is described below
commit 021b7f511f621394bfa1684009d64e16afd1cbde
Author: Dominik Riemer <[email protected]>
AuthorDate: Mon Dec 4 15:00:52 2023 +0100
feat(#2269): Add basic auth to prometheus monitoring endpoint
---
.../security/UnauthorizedRequestEntryPoint.java | 2 +-
.../core/filter/TokenAuthenticationFilter.java | 43 +++++++++++++++++++++-
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git
a/streampipes-service-base/src/main/java/org/apache/streampipes/service/base/security/UnauthorizedRequestEntryPoint.java
b/streampipes-service-base/src/main/java/org/apache/streampipes/service/base/security/UnauthorizedRequestEntryPoint.java
index 144a990dc..94304a6d5 100644
---
a/streampipes-service-base/src/main/java/org/apache/streampipes/service/base/security/UnauthorizedRequestEntryPoint.java
+++
b/streampipes-service-base/src/main/java/org/apache/streampipes/service/base/security/UnauthorizedRequestEntryPoint.java
@@ -35,7 +35,7 @@ public class UnauthorizedRequestEntryPoint implements
AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException {
- LOG.error("Unauthorized request to {}", httpServletRequest.getPathInfo());
+ LOG.error("Unauthorized request to {}",
httpServletRequest.getServletPath());
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
e.getLocalizedMessage());
}
diff --git
a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
index e389f4afb..47f9dd018 100644
---
a/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
+++
b/streampipes-service-core/src/main/java/org/apache/streampipes/service/core/filter/TokenAuthenticationFilter.java
@@ -24,11 +24,13 @@ import
org.apache.streampipes.model.client.user.ServiceAccount;
import org.apache.streampipes.model.client.user.UserAccount;
import org.apache.streampipes.storage.api.IUserStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
+import
org.apache.streampipes.user.management.encryption.SecretEncryptionManager;
import org.apache.streampipes.user.management.jwt.JwtTokenProvider;
import org.apache.streampipes.user.management.model.PrincipalUserDetails;
import org.apache.streampipes.user.management.model.ServiceAccountDetails;
import org.apache.streampipes.user.management.model.UserAccountDetails;
import org.apache.streampipes.user.management.service.TokenService;
+import org.apache.streampipes.user.management.util.PasswordUtil;
import org.apache.streampipes.user.management.util.TokenUtil;
import org.slf4j.Logger;
@@ -45,12 +47,20 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Base64;
+import java.util.List;
public class TokenAuthenticationFilter extends OncePerRequestFilter {
private final JwtTokenProvider tokenProvider;
private final IUserStorage userStorage;
+ private final List<String> supportedBasicAuthPaths = List.of(
+ "/actuator/prometheus"
+ );
+
private static final Logger logger =
LoggerFactory.getLogger(TokenAuthenticationFilter.class);
public TokenAuthenticationFilter() {
@@ -68,7 +78,7 @@ public class TokenAuthenticationFilter extends
OncePerRequestFilter {
if (StringUtils.hasText(jwt) && tokenProvider.validateJwtToken(jwt)) {
String username = tokenProvider.getUserIdFromToken(jwt);
applySuccessfulAuth(request, username);
- } else {
+ } else if (isApiKeyAuth(request)) {
String apiKey = getApiKeyFromRequest(request);
String apiUser = getApiUserFromRequest(request);
if (StringUtils.hasText(apiKey) && StringUtils.hasText(apiUser)) {
@@ -78,6 +88,22 @@ public class TokenAuthenticationFilter extends
OncePerRequestFilter {
applySuccessfulAuth(request, apiUser);
}
}
+ } else {
+ var authorizationHeader = request.getHeader("Authorization");
+ if (authorizationHeader != null &&
authorizationHeader.startsWith("Basic ")) {
+ if (supportedBasicAuthPaths.contains(request.getServletPath())) {
+ String base64Credentials = authorizationHeader.substring("Basic
".length()).trim();
+ String credentials = new
String(Base64.getDecoder().decode(base64Credentials));
+
+ String[] splitCredentials = credentials.split(":");
+ String username = splitCredentials[0];
+ String providedProperty = splitCredentials[1];
+ var principal =
StorageDispatcher.INSTANCE.getNoSqlStore().getUserStorageAPI().getUser(username);
+ if (principal != null && checkCredentials(principal,
providedProperty)) {
+ applySuccessfulAuth(request, username);
+ }
+ }
+ }
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context",
ex);
@@ -86,6 +112,21 @@ public class TokenAuthenticationFilter extends
OncePerRequestFilter {
filterChain.doFilter(request, response);
}
+ private boolean checkCredentials(Principal principal, String
providedProperty)
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
+ if (principal instanceof UserAccount) {
+ return PasswordUtil.validatePassword(providedProperty, ((UserAccount)
principal).getPassword());
+ } else if (principal instanceof ServiceAccount) {
+ return
providedProperty.equals(SecretEncryptionManager.decrypt(((ServiceAccount)
principal).getClientSecret()));
+ } else {
+ throw new IllegalArgumentException("Unknown user instance");
+ }
+ }
+
+ private boolean isApiKeyAuth(HttpServletRequest request) {
+ return request.getHeader(HttpConstants.X_API_USER) != null &&
request.getHeader(HttpConstants.X_API_KEY) != null;
+ }
+
private void applySuccessfulAuth(HttpServletRequest request,
String username) {
Principal user = userStorage.getUser(username);