adalid.jaas.google.GoogleRecaptcha.java Source code

Java tutorial

Introduction

Here is the source code for adalid.jaas.google.GoogleRecaptcha.java

Source

/*
 * Este programa es software libre; usted puede redistribuirlo y/o modificarlo bajo los terminos
 * de la licencia "GNU General Public License" publicada por la Fundacion "Free Software Foundation".
 * Este programa se distribuye con la esperanza de que pueda ser util, pero SIN NINGUNA GARANTIA;
 * vea la licencia "GNU General Public License" para obtener mas informacion.
 */
package adalid.jaas.google;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.servlet.http.HttpServletRequest;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

/**
 * @author Jorge Campins
 */
public class GoogleRecaptcha {

    //  <editor-fold defaultstate="collapsed" desc="quick-setup">
    //  Edit web/resources/javascript3.js in the war module of your enterprise project.
    //  Find the return statement of function grecaptchaSiteKey and replace the returned value with your site key.
    //
    //  Add a property named google.recaptcha.secret.key to the application server system properties; the property
    //  value should be your secret key. Alternatively, store your secret key in a file and add a property named
    //  google.recaptcha.secret.key.file to the application server system properties; the property value should be
    //  the absolute path of the file containing your secret key. Alternatively, store your secret key in a file
    //  named google.recaptcha.secret.key in the application server user directory.
    //
    //  </editor-fold>
    //
    public static final String RESPONSE_SUCCESSFULLY_VERIFIED = "Google ReCAPTCHA: user's response successfully verified";

    public static final String RESPONSE_COULD_NOT_BE_VERIFIED = "Google ReCAPTCHA: user's response could not be verified";

    private static final Logger logger = Logger.getLogger(GoogleRecaptcha.class.getName());

    private static final String USER_DIR = System.getProperties().getProperty("user.dir");

    private static final String FILE_SEP = System.getProperties().getProperty("file.separator");

    private static final String SECRET_KEY_PROPERTY_KEY = "google.recaptcha.secret.key";

    private static final String SECRET_KEY_FILE_PROPERTY_KEY = "google.recaptcha.secret.key.file";

    private static final String SECRET_KEY_FILE_DEFAULT_PATH = USER_DIR + FILE_SEP + SECRET_KEY_PROPERTY_KEY;

    private static final String MISSING_SECRET_KEY = "Google ReCAPTCHA secret key is missing; test secret key will be used";

    private static final String DEFAULT_SECRET_KEY = "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe";

    private static final Level TRACE = Level.FINE;

    private static final String PARAMETER_KEY = "g-recaptcha-response";

    private static final String VALIDATOR_KEY = "g-recaptcha-response-validator";

    private static final String SECRET_KEY = secretKey();

    private static final boolean VERIFY_NULL_RESPONSE = true;

    private static String secretKey() {
        logger.log(Level.INFO, VALIDATOR_KEY + " = {0}", GoogleRecaptcha.class.getName());
        String secretKey = System.getProperties().getProperty(SECRET_KEY_PROPERTY_KEY);
        if (secretKey == null || secretKey.isEmpty()) {
            String path = secretKeyFilePath();
            File file = new File(path);
            if (file.isFile()) {
                logger.log(TRACE, SECRET_KEY_FILE_PROPERTY_KEY + " = {0}", path);
                try {
                    secretKey = new Scanner(file).useDelimiter("\\Z").next();
                } catch (FileNotFoundException ex) {
                    logger.log(Level.WARNING, SECRET_KEY_FILE_PROPERTY_KEY + " {0} is missing", path);
                }
            } else {
                logger.log(Level.WARNING, SECRET_KEY_FILE_PROPERTY_KEY + " {0} is missing or invalid", path);
            }
        }
        if (secretKey == null || secretKey.isEmpty()) {
            logger.log(Level.WARNING, MISSING_SECRET_KEY);
            return DEFAULT_SECRET_KEY;
        }
        return secretKey;
    }

    private static String secretKeyFilePath() {
        String path = System.getProperties().getProperty(SECRET_KEY_FILE_PROPERTY_KEY);
        return path == null || path.isEmpty() ? SECRET_KEY_FILE_DEFAULT_PATH
                : path.replace('\\', '/').replace("/", FILE_SEP);
    }

    public static boolean verifyUserResponse() {
        String userResponse = getRequestParameter(PARAMETER_KEY);
        return verify(userResponse);
    }

    private static String getRequestParameter(String key) {
        if (key == null) {
            return null;
        }
        Object request;
        try {
            request = PolicyContext.getContext(HttpServletRequest.class.getName());
        } catch (PolicyContextException ex) {
            logger.log(Level.SEVERE, ex.toString(), ex);
            return null;
        }
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String parameter = httpServletRequest.getParameter(key);
            logger.log(TRACE, "{0}: {1}", new Object[] { key, parameter });
            return parameter;
        }
        logger.log(TRACE, "HTTP Servlet Request: {0}", request);
        return null;
    }

    private static boolean verify(String userResponse) {
        if (userResponse == null) {
            return VERIFY_NULL_RESPONSE;
        }
        URIBuilder builder = new URIBuilder();
        builder.setScheme("https");
        builder.setHost("www.google.com");
        builder.setPath("/recaptcha/api/siteverify");
        //      builder.clearParameters();
        builder.setParameter("secret", SECRET_KEY);
        builder.setParameter("response", userResponse);
        URI uri;
        try {
            uri = builder.build();
        } catch (URISyntaxException ex) {
            logger.log(Level.SEVERE, ex.toString(), ex);
            return false;
        }
        HttpUriRequest request = (HttpUriRequest) new HttpGet(uri);
        try (CloseableHttpClient client = HttpClients.createDefault()) {
            try (CloseableHttpResponse response = client.execute(request)) {
                StatusLine statusLine = response.getStatusLine();
                logger.log(TRACE, "Status Line: {0}", statusLine);
                if (statusLine.getReasonPhrase().equals("OK")) {
                    return success(response.getEntity());
                }
            } catch (ClientProtocolException ex) {
                logger.log(Level.SEVERE, ex.toString(), ex);
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, ex.toString(), ex);
        }
        return false;
    }

    private static boolean success(HttpEntity entity) throws IOException {
        if (entity == null) {
            return false;
        }
        logger.log(TRACE, "{0}", entity.getContentType());
        BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
        String line, string = "";
        while ((line = reader.readLine()) != null) {
            string += line;
        }
        logger.log(TRACE, "Content: {0}", string);
        boolean success = success(string);
        if (success) {
            logger.log(TRACE, RESPONSE_SUCCESSFULLY_VERIFIED);
        } else {
            logger.log(TRACE, RESPONSE_COULD_NOT_BE_VERIFIED);
        }
        return success;
    }

    private static boolean success(String jsonString) {
        JsonObject jsonObject;
        try (JsonReader jsonReader = Json.createReader(new StringReader(jsonString))) {
            jsonObject = jsonReader.readObject();
            return jsonObject.getBoolean("success");
        }
    }

}