AuthenticationHandler extends AbstractHandler { @Override public boolean handleRequest(org.apache.synapse.MessageContext messageContext) { org.apache.axis2.context.MessageContext axisMC = ((Axis2MessageContext) messageContext).getAxis2MessageContext(); String ctxPath = messageContext.getTo().getAddress().trim(); if (log.isDebugEnabled()) { log.debug("Authentication handler invoked by: " + ctxPath); } Map<String, String> headers = (Map<String, String>) axisMC.getProperty(MessageContext.TRANSPORT_HEADERS); try { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); RESTResponse response = null; if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE); if (log.isDebugEnabled()) { log.debug("Verify Cert:\n" + mdmSignature); } String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); if (deviceType == null) { return false; } URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); Map<String, String> certVerifyHeaders = this.setHeaders(this.restInvoker); Certificate certificate = new Certificate(); certificate.setPem(mdmSignature); certificate.setTenantId(tenantId); certificate.setSerial(""); Gson gson = new Gson(); String certVerifyContent = gson.toJson(certificate); response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, certVerifyContent); String str = response.getContent(); if (log.isDebugEnabled()) { log.debug("Verify response:" + response.getContent()); log.debug("Response String : " + str); } if (response.getHttpStatus() == 200 && str.contains(JWTTOKEN)) { ValidationResponce validationResponce = gson.fromJson(str, ValidationResponce.class); headers.put(X_JWT_ASSERTION, validationResponce.getJWTToken()); } else { return false; } } else if (headers.containsKey(AuthConstants.PROXY_MUTUAL_AUTH_HEADER)) { String subjectDN = headers.get(AuthConstants.PROXY_MUTUAL_AUTH_HEADER); if (log.isDebugEnabled()) { log.debug("Verify subject DN: " + subjectDN); } String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); Map<String, String> certVerifyHeaders = this.setHeaders(this.restInvoker); Certificate certificate = new Certificate(); certificate.setPem(subjectDN); certificate.setTenantId(tenantId); certificate.setSerial(AuthConstants.PROXY_MUTUAL_AUTH_HEADER); Gson gson = new Gson(); String certVerifyContent = gson.toJson(certificate); response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, certVerifyContent); if (log.isDebugEnabled()) { log.debug("Verify response:" + response.getContent()); } } else if (headers.containsKey(AuthConstants.MUTUAL_AUTH_HEADER)) { javax.security.cert.X509Certificate[] certs = (javax.security.cert.X509Certificate[]) axisMC.getProperty(AuthConstants.CLIENT_CERTIFICATE); CertificateFactory cf = CertificateFactory.getInstance("X.509"); ByteArrayInputStream bais = new ByteArrayInputStream(certs[0].getEncoded()); X509Certificate x509 = (X509Certificate) cf.generateCertificate(bais); bais.close(); if (x509 != null) { headers.put(AuthConstants.PROXY_MUTUAL_AUTH_HEADER, CertificateGenerator.getCommonName(x509)); return true; } } else if (headers.containsKey(AuthConstants.ENCODED_PEM)) { String encodedPem = headers.get(AuthConstants.ENCODED_PEM); if (log.isDebugEnabled()) { log.debug("Verify Cert:\n" + encodedPem); } String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); Map<String, String> certVerifyHeaders = this.setHeaders(this.restInvoker); Certificate certificate = new Certificate(); certificate.setPem(encodedPem); certificate.setTenantId(tenantId); certificate.setSerial(""); Gson gson = new Gson(); String certVerifyContent = gson.toJson(certificate); response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, certVerifyContent); if (log.isDebugEnabled()) { log.debug("Verify response:" + response.getContent()); } } else { log.warn("Unauthorized request for api: " + ctxPath); return false; } if (response != null && !response.getContent().contains("invalid")) { return true; } log.warn("Unauthorized request for api: " + ctxPath); return false; } catch (IOException e) { log.error("Error while processing certificate.", e); return false; } catch (URISyntaxException e) { log.error("Error while processing certificate.", e); return false; } catch (APIMCertificateMGTException e) { log.error("Error while processing certificate.", e); return false; } catch (CertificateException e) { log.error("Certificate issue occurred when generating converting PEM to x509Certificate", e); return false; } catch (CertificateEncodingException e) { log.error("Error while attempting to encode certificate.", e); return false; } } AuthenticationHandler(); @Override boolean handleRequest(org.apache.synapse.MessageContext messageContext); @Override boolean handleResponse(org.apache.synapse.MessageContext messageContext);  }
@Test(description = "Handle request with empty transport headers") public void testHandleRequestWithEmptyTransportHeader() throws Exception { boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration, new HashMap<>(), "https: Assert.assertFalse(response); }
@Test(description = "Handle request with without device type", dependsOnMethods = "testHandleRequestWithEmptyTransportHeader") public void testHandleRequestWithoutDeviceType() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert"); boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: Assert.assertFalse(response); }
@Test(description = "Handle request with device type URI with MDM ceritificate", dependsOnMethods = "testHandleRequestWithoutDeviceType") public void testHandleSuccessfulRequestMDMCertificate() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert"); setMockClient(); this.mockClient.setResponse(getDCRResponse()); this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: Assert.assertTrue(response); this.mockClient.reset(); }
@Test(description = "Handle request with device type URI with Proxy Mutual Auth Header", dependsOnMethods = "testHandleSuccessfulRequestMDMCertificate") public void testHandleSuccessRequestProxyMutualAuthHeader() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.PROXY_MUTUAL_AUTH_HEADER, "Test Header"); setMockClient(); this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); boolean response = this.handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: Assert.assertTrue(response); this.mockClient.reset(); }
@Test(description = "Handle request with device type URI with Mutual Auth Header", dependsOnMethods = "testHandleSuccessRequestProxyMutualAuthHeader") public void testHandleSuccessRequestMutualAuthHeader() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MUTUAL_AUTH_HEADER, "Test Header"); setMockClient(); this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: org.apache.axis2.context.MessageContext axisMC = ((Axis2MessageContext) messageContext).getAxis2MessageContext(); String certStr = getContent(TestUtils.getAbsolutePathOfConfig("ra_cert.pem")); X509Certificate cert = X509Certificate.getInstance(new ByteArrayInputStream(certStr. getBytes(StandardCharsets.UTF_8.name()))); axisMC.setProperty(AuthConstants.CLIENT_CERTIFICATE, new X509Certificate[]{cert}); boolean response = this.handler.handleRequest(messageContext); Assert.assertTrue(response); this.mockClient.reset(); }
@Test(description = "Handle request with device type URI with Encoded Pem", dependsOnMethods = "testHandleSuccessRequestMutualAuthHeader") public void testHandleSuccessRequestEncodedPem() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: boolean response = this.handler.handleRequest(messageContext); Assert.assertTrue(response); this.mockClient.reset(); }
@Test(description = "Handle request with device type URI with Encoded Pem with invalid response", dependsOnMethods = "testHandleSuccessRequestEncodedPem") public void testHandleSuccessRequestEncodedPemInvalidResponse() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getInvalidResponse()); MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: boolean response = this.handler.handleRequest(messageContext); Assert.assertFalse(response); this.mockClient.reset(); }
@Test(description = "Handle request with cert management exception ", dependsOnMethods = "testHandleSuccessRequestEncodedPem") public void testHandleRequestWithCertMgmtException() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); this.mockClient.setResponse(null); MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: boolean response = this.handler.handleRequest(messageContext); Assert.assertFalse(response); this.mockClient.reset(); }
@Test(description = "Handle request with IO exception", dependsOnMethods = "testHandleRequestWithCertMgmtException") public void testHandleRequestWithIOException() throws Exception { HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(null); MessageContext messageContext = createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: boolean response = this.handler.handleRequest(messageContext); Assert.assertFalse(response); this.mockClient.reset(); }
@Test(description = "Handle request with URI exception", dependsOnMethods = "testHandleRequestWithIOException") public void testHandleRequestWithURIException() throws Exception { TestUtils.resetSystemProperties(); HashMap<String, String> transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert"); AuthenticationHandler handler = new AuthenticationHandler(); boolean response = handler.handleRequest(createSynapseMessageContext("<empty/>", this.synapseConfiguration, transportHeaders, "https: Assert.assertFalse(response); TestUtils.setSystemProperties(); }