This post is complementary to this oneI asked the question about implementing DropBox's Share link functionality on the server side in the most secure way. Of course, real security involves at least password-based authentication, not this security by obscurity approach, but the guys from DropBox managed to implement this somehow :)Here is the code I've written for this task. I would be grateful for any comments and criticism for this small piece of code.package com.test;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.PrintWriter;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * * @author Anton P. Kolosov */public class ObscureSecureServlet extends HttpServlet {    private static final Pattern UUID_PATTERN = Pattern.compile(^[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$, Pattern.CASE_INSENSITIVE);    private String basePath;    /**     * Initialization routines     * @param config Servlet configuration     * @throws ServletException     */    public void init(ServletConfig config) throws ServletException {        super.init(config);        basePath = config.getInitParameter(basePath);    }    /**     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.     *     * @param request servlet request     * @param response servlet response     * @throws ServletException if a servlet-specific error occurs     * @throws IOException if an I/O error occurs     */    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        String res = request.getParameter(res);        String name = request.getParameter(name);        Matcher matcher = UUID_PATTERN.matcher(res);        if (matcher.matches()) {            // Only UUIDs are allowed for res parameter            File file = new File(basePath + / + res, name);            if (file.exists()) {                sendFile(file, request, response);                return;            }        }        // Can redirect to jsp if you wish...        response.setContentType(text/html;charset=UTF-8);        try (PrintWriter out = response.getWriter()) {            out.println(<!DOCTYPE html>);            out.println(<html>);            out.println(<head>);            out.println(<title>File not found</title>);                        out.println(</head>);            out.println(<body>);            out.println(File for res =  + res +  and name =  + name +  was not found!);            out.println(</body>);            out.println(</html>);        }    }    private void sendFile(File file, HttpServletRequest request, HttpServletResponse response) throws IOException {        long fileSize = file.length();        response.setHeader(Content-length, Long.toString(fileSize));        response.setContentType(application/octet-stream);        response.setHeader( Content-Disposition, filename=\ + file.getName() + \ );        ServletOutputStream out = response.getOutputStream();        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(out);        write(file, bufferedOutputStream);        bufferedOutputStream.flush();    }    /**     * Writes a document to the passed stream.     * @param bufferedOutput The method writes name to this output stream     * @throws IOException IOException     */    public void write(File file, BufferedOutputStream bufferedOutput) throws IOException {        byte buffer[] = new byte[1024 * 4];        BufferedInputStream  bufferedInput = null;        try {            FileInputStream inputStream = new FileInputStream(file);            bufferedInput = new BufferedInputStream(inputStream);            int lengthRead = 0;            int offset = 0;            while (true) {                lengthRead = bufferedInput.read(buffer, 0, buffer.length);                if (lengthRead == -1) {                    break;                }                bufferedOutput.write(buffer, 0, lengthRead);                offset += lengthRead;            }        } finally {            if (bufferedInput != null) {                bufferedInput.close();            }        }    }    // <editor-fold defaultstate=collapsed desc=HttpServlet methods. Click on the + sign on the left to edit the code.>    /**     * Handles the HTTP <code>GET</code> method.     *     * @param request servlet request     * @param response servlet response     * @throws ServletException if a servlet-specific error occurs     * @throws IOException if an I/O error occurs     */    @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        processRequest(request, response);    }    /**     * Handles the HTTP <code>POST</code> method.     *     * @param request servlet request     * @param response servlet response     * @throws ServletException if a servlet-specific error occurs     * @throws IOException if an I/O error occurs     */    @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        processRequest(request, response);    }    /**     * Returns a short description of the servlet.     *     * @return a String containing servlet description     */    @Override    public String getServletInfo() {        return Servlet for 'obscure secure' file retrieving;    }// </editor-fold>}
Placing secure data in Java web application
java;security