This commit is contained in:
Anthony Stirling 2024-01-10 00:39:26 +00:00
parent 32da14acbf
commit 873a4ecb7e

View file

@ -1,12 +1,9 @@
package stirling.software.SPDF.config.security; package stirling.software.SPDF.config.security;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -21,7 +18,6 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import stirling.software.SPDF.model.ApiKeyAuthenticationToken; import stirling.software.SPDF.model.ApiKeyAuthenticationToken;
@Component @Component
@ -35,28 +31,14 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
@Qualifier("loginEnabled") @Qualifier("loginEnabled")
public boolean loginEnabledValue; public boolean loginEnabledValue;
@Value("${redirect.port:}") // Default to empty if not set
private String redirectPort;
@Override @Override
protected void doFilterInternal( protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException { throws ServletException, IOException {
// Custom response wrapper to modify the redirect location
HttpServletResponseWrapper responseWrapper =
new HttpServletResponseWrapper(response) {
@Override
public void sendRedirect(String location) throws IOException {
// Modify the location to include the correct port
String modifiedLocation = modifyLocation(location, request);
super.sendRedirect(modifiedLocation);
}
};
if (!loginEnabledValue) { if (!loginEnabledValue) {
// If login is not enabled, just pass all requests without authentication // If login is not enabled, just pass all requests without authentication
filterChain.doFilter(request, responseWrapper); filterChain.doFilter(request, response);
return; return;
} }
String requestURI = request.getRequestURI(); String requestURI = request.getRequestURI();
@ -71,8 +53,8 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
// provider for API keys. // provider for API keys.
UserDetails userDetails = userService.loadUserByApiKey(apiKey); UserDetails userDetails = userService.loadUserByApiKey(apiKey);
if (userDetails == null) { if (userDetails == null) {
responseWrapper.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
responseWrapper.getWriter().write("Invalid API Key."); response.getWriter().write("Invalid API Key.");
return; return;
} }
authentication = authentication =
@ -81,8 +63,8 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
// If API key authentication fails, deny the request // If API key authentication fails, deny the request
responseWrapper.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
responseWrapper.getWriter().write("Invalid API Key."); response.getWriter().write("Invalid API Key.");
return; return;
} }
} }
@ -94,37 +76,18 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
String contextPath = request.getContextPath(); String contextPath = request.getContextPath();
if ("GET".equalsIgnoreCase(method) && !(contextPath + "/login").equals(requestURI)) { if ("GET".equalsIgnoreCase(method) && !(contextPath + "/login").equals(requestURI)) {
responseWrapper.sendRedirect(contextPath + "/login"); // redirect to the login page response.sendRedirect(contextPath + "/login"); // redirect to the login page
return; return;
} else { } else {
responseWrapper.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
responseWrapper response.getWriter()
.getWriter()
.write( .write(
"Authentication required. Please provide a X-API-KEY in request header.\nThis is found in Settings -> Account Settings -> API Key\nAlternativly you can disable authentication if this is unexpected"); "Authentication required. Please provide a X-API-KEY in request header.\nThis is found in Settings -> Account Settings -> API Key\nAlternativly you can disable authentication if this is unexpected");
return; return;
} }
} }
filterChain.doFilter(request, responseWrapper); filterChain.doFilter(request, response);
}
private String modifyLocation(String location, HttpServletRequest request) {
if (!location.matches("https?://[^/]+:\\d+.*")
&& redirectPort != null
&& redirectPort.length() > 0) {
try {
int port = Integer.parseInt(redirectPort); // Parse the port
URL url = new URL(location);
String modifiedUrl =
new URL(url.getProtocol(), url.getHost(), port, url.getFile()).toString();
return modifiedUrl;
} catch (MalformedURLException | NumberFormatException e) {
// Log error and return the original location if URL parsing fails
e.printStackTrace();
}
}
return location;
} }
@Override @Override