Java tutorial
/** * Copyright 2016 PerimeterX, Inc. * * Permission is hereby granted, free of charge, to any * * person obtaining a copy of this software and associated * * documentation files (the "Software"), to deal in the * * Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the * * Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice * * shall be included in all copies or substantial portions of * * the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * * PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE AUTHORS * * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.perimeterx.api; import com.perimeterx.api.activities.ActivityHandler; import com.perimeterx.api.activities.DefaultActivityHandler; import com.perimeterx.api.blockhandler.BlockHandler; import com.perimeterx.api.blockhandler.CaptchaBlockHandler; import com.perimeterx.api.blockhandler.DefaultBlockHandler; import com.perimeterx.api.ip.IPProvider; import com.perimeterx.api.ip.RemoteAddressIPProvider; import com.perimeterx.http.PXHttpClient; import com.perimeterx.internals.PXCaptchaValidator; import com.perimeterx.internals.PXCookieValidator; import com.perimeterx.internals.PXS2SValidator; import com.perimeterx.models.PXContext; import com.perimeterx.models.exceptions.PXException; import com.perimeterx.models.httpmodels.RiskRequest; import com.perimeterx.models.httpmodels.RiskResponse; import com.perimeterx.models.risk.BlockReason; import com.perimeterx.models.risk.S2SCallReason; import com.perimeterx.utils.Constants; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponseWrapper; /** * Facade object for - configuring, validating and blocking requests * <p> * Created by shikloshi on 03/07/2016. */ public class PerimeterX { Logger logger = LoggerFactory.getLogger(PerimeterX.class); private static PerimeterX instance = null; private PXConfiguration configuration; private BlockHandler blockHandler; private PXS2SValidator serverValidator; private PXCookieValidator cookieValidator; private ActivityHandler activityHandler; private PXCaptchaValidator captchaValidator; private IPProvider ipProvider; /** * Build a singleton object from configuration * * @param configuration - {@link PXConfiguration} * @return PerimeterX object * @throws PXException */ public static PerimeterX getInstance(PXConfiguration configuration) throws PXException { if (instance == null) { synchronized (PerimeterX.class) { if (instance == null) { instance = new PerimeterX(configuration); } } } return instance; } private PerimeterX(PXConfiguration configuration) throws PXException { PXHttpClient pxClient = PXHttpClient.getInstance(configuration.getServerURL(), configuration.getApiTimeout(), configuration.getAuthToken()); this.configuration = configuration; if (this.configuration.isCaptchaEnabled()) { this.blockHandler = new CaptchaBlockHandler(); } else { this.blockHandler = new DefaultBlockHandler(); } this.serverValidator = new PXS2SValidator(pxClient); this.captchaValidator = new PXCaptchaValidator(pxClient); this.activityHandler = new DefaultActivityHandler(pxClient, configuration); this.cookieValidator = PXCookieValidator.getDecoder(configuration.getCookieKey()); this.ipProvider = new RemoteAddressIPProvider(); } /** * Verify http request using cookie or PX server call * * @param req - current http call examined by PX * @param responseWrapper - response wrapper on which we will set the response according to PX verification. {@see javax.xml.ws.ResponseWrapper} * @throws PXException */ public boolean pxVerify(HttpServletRequest req, HttpServletResponseWrapper responseWrapper) throws PXException { if (!moduleEnabled()) { logger.info("PerimeterX verification SDK is disabled"); return true; } // Remove captcha cookie to prevent re-use Cookie cookie = new Cookie(Constants.COOKIE_CAPTCHA_KEY, StringUtils.EMPTY); cookie.setMaxAge(0); responseWrapper.addCookie(cookie); PXContext context = new PXContext(req, this.ipProvider, configuration.getAppId()); if (captchaValidator.verify(context)) { return handleVerification(context, responseWrapper, BlockReason.COOKIE); } S2SCallReason callReason = cookieValidator.verify(context); logger.info("Risk API call reason: {}", callReason); // Cookie is valid (exists and not expired) so we can block according to it's score if (callReason == S2SCallReason.NONE) { logger.info("No risk API Call is needed, using cookie"); return handleVerification(context, responseWrapper, BlockReason.COOKIE); } context.setS2sCallReason(callReason); // Calls risk_api and populate the data retrieved to the context RiskRequest request = RiskRequest.fromContext(context); RiskResponse response = serverValidator.verify(request); context.setScore(response.getScores().getNonHuman()); context.setUuid(response.getUuid()); return handleVerification(context, responseWrapper, BlockReason.SERVER); } private boolean handleVerification(PXContext context, HttpServletResponseWrapper responseWrapper, BlockReason blockReason) throws PXException { int score = context.getScore(); int blockingScore = this.configuration.getBlockingScore(); // If should block this request we will apply our block handle and send the block activity to px boolean verified = score < blockingScore; logger.info("Request score: {}, Blocking score: {}", score, blockingScore); if (verified) { logger.info("Request valid"); // Not blocking request and sending page_requested activity to px if configured as true if (this.configuration.shouldSendPageActivities()) { this.activityHandler.handlePageRequestedActivity(context); } } else { logger.info("Request invalid"); context.setBlockReason(blockReason); this.activityHandler.handleBlockActivity(context); this.blockHandler.handleBlocking(context, responseWrapper); } return verified; } private boolean moduleEnabled() { return this.configuration.isModuleEnabled(); } /** * Set activity handler * * @param activityHandler - new activity handler to use */ public void setActivityHandler(ActivityHandler activityHandler) { this.activityHandler = activityHandler; } /** * Set block handler * * @param blockHandler - new block handler to use */ public void setBlockHandler(BlockHandler blockHandler) { this.blockHandler = blockHandler; } /** * Set IP Provider * * @param ipProvider - IP provider that is used to extract ip from request */ public void setIpProvider(IPProvider ipProvider) { this.ipProvider = ipProvider; } }