Open ilkin opened 2 years ago
Will consider it in a future release. Contribution would also be appreciated ;)
+1, this would be useful
@ilkin @grig0ry Do have any specific authentication method in mind? LDAP, OAuth, SAML2, etc.
Please make this optional. Our use case would be crippled with forced authentication.
@smuda yes in case this is getting implemented authentication will be optional.
@ilkin / @grig0ry can you please elaborate in more detail the need for authentication? The tool is intended for development purposes only.
@gessnerfl In our case, we run test builds of the application publicly, for QA and the development team. With a secure web UI, it would be calmer :)
Also, we are using it for QA and UAT purposes and it is a public server in the company that many users can access, so simple authentication might be good at least.
Just a thought: We also use fakesmtp, which contains non-public data in testcases. Therefore we added traefik as a reverse proxy with basic authentication before and made fakesmtp website accessible only through traefik, see https://doc.traefik.io/traefik/middlewares/http/basicauth/ Maybe this could be a simple solution without the need to change a line in fakesmtp.
This is our docker-compose file (no exposed ports for web interface):
version: '3'
services:
k-fakesmtp:
# https://hub.docker.com/r/gessnerfl/fake-smtp-server
# https://github.com/gessnerfl/fake-smtp-server
image: gessnerfl/fake-smtp-server
container_name: k-fakesmtp
environment:
- TZ=Europe/Zurich
volumes:
- ./mountpoints/application.properties:/root/application.properties:ro
entrypoint: ["java",
"-Djava.security.egd=file:/dev/./urandom",
"-Dfile.encoding=utf-8",
"-cp", "@/app/jib-classpath-file",
"de.gessnerfl.fakesmtp.Application",
"--spring.config.location=/root/application.properties"]
labels:
- traefik.enable=true
- traefik.http.routers.fakesmtpHTTPS.rule=Host(`fakesmtp-dev01.company.com`)
- traefik.http.routers.fakesmtpHTTPS.tls=true
- traefik.http.routers.fakesmtpHTTPS.middlewares=basicAuthForUsers@file
- traefik.http.services.fakesmtp.loadbalancer.server.port=5080
networks:
- traefik_shared
ports:
- 5025:5025
# do NOT expose ports 5080 / 5081 as we want to have basicAuth from traefik
networks:
traefik_shared:
external:
name: traefik_shared
Not sure if it is useful for anybody but you can implement a quick and dirty, but easy solution with this class. You could redirect to a login page if the right cookie is not found to set the right cookie.
package proxy;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer;
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.URL; import java.util.List; import java.util.Map;
public class ReverseProxyServer {
private static final int PORT = 8000;
private static final String DESTINATION_URL = "http://localhost:8080";
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(PORT), 0);
server.createContext("/", new RequestHandler());
server.start();
System.out.println("Reverse Proxy Server started on port " + PORT);
}
static class RequestHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
String requestMethod = exchange.getRequestMethod();
String requestPath = exchange.getRequestURI().getPath();
String requestQuery = exchange.getRequestURI().getQuery();
System.out.println(requestQuery);
String destinationUrl = DESTINATION_URL + requestPath + "?" + requestQuery;
HttpURLConnection connection = (HttpURLConnection) new URL(destinationUrl).openConnection();
connection.setRequestMethod(requestMethod);
// Forward headers from the original request to the destination
for (String header : exchange.getRequestHeaders().keySet()) {
connection.setRequestProperty(header, exchange.getRequestHeaders().getFirst(header));
}
// Copy the cookies from the original request to the destination
Map<String, List<String>> cookieHeaders = exchange.getRequestHeaders();
if (cookieHeaders.containsKey("Cookie")) {
String cookies = String.join("; ", cookieHeaders.get("Cookie"));
System.out.println(cookies);
connection.setRequestProperty("Cookie", cookies);
}
// Copy the response from the destination to the client
try (OutputStream outputStream = exchange.getResponseBody();
InputStream inputStream = connection.getInputStream()) {
exchange.sendResponseHeaders(connection.getResponseCode(), 0);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} finally {
connection.disconnect();
}
}
}
}
Please add login page to authenticate fakesmtp interface. Authentication could be optional and Username and password can canfigure in application.properties.