|
|
@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
|
|
|
|
import org.apache.ws.security.WSConstants;
|
|
|
|
import org.apache.ws.security.WSConstants;
|
|
|
|
import org.apache.ws.security.WSSecurityException;
|
|
|
|
import org.apache.ws.security.WSSecurityException;
|
|
|
|
import org.apache.ws.security.util.Base64;
|
|
|
|
import org.apache.ws.security.util.Base64;
|
|
|
|
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
import org.wso2.carbon.apimgt.handlers.invoker.RESTInvoker;
|
|
|
|
import org.wso2.carbon.apimgt.handlers.invoker.RESTInvoker;
|
|
|
|
import org.wso2.carbon.apimgt.handlers.invoker.RESTResponse;
|
|
|
|
import org.wso2.carbon.apimgt.handlers.invoker.RESTResponse;
|
|
|
@ -37,7 +38,9 @@ import org.wso2.carbon.apimgt.handlers.utils.AuthConstants;
|
|
|
|
import org.wso2.carbon.apimgt.handlers.utils.CoreUtils;
|
|
|
|
import org.wso2.carbon.apimgt.handlers.utils.CoreUtils;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.xml.namespace.QName;
|
|
|
|
import javax.xml.namespace.QName;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.URI;
|
|
|
|
import java.net.URI;
|
|
|
|
|
|
|
|
import java.net.URISyntaxException;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
@ -68,64 +71,81 @@ public class AuthenticationHandler implements Handler {
|
|
|
|
* @throws AxisFault
|
|
|
|
* @throws AxisFault
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {
|
|
|
|
public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {
|
|
|
|
boolean validateRequest = messageContext.getTo() != null;
|
|
|
|
if (isSecuredAPI(messageContext)) {
|
|
|
|
|
|
|
|
|
|
|
|
if (validateRequest && isSecuredAPI(messageContext)) {
|
|
|
|
|
|
|
|
String ctxPath = messageContext.getTo().getAddress().trim();
|
|
|
|
String ctxPath = messageContext.getTo().getAddress().trim();
|
|
|
|
CoreUtils.debugLog(log, "Authentication handler invoked by: ", ctxPath);
|
|
|
|
CoreUtils.debugLog(log, "Authentication handler invoked by: ", ctxPath);
|
|
|
|
Map<?, ?> headers = (Map<?, ?>) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS);
|
|
|
|
Map<?, ?> headers = (Map<?, ?>) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS);
|
|
|
|
|
|
|
|
try {
|
|
|
|
if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) {
|
|
|
|
if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) {
|
|
|
|
String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString();
|
|
|
|
CoreUtils.debugLog(log, "Verify Cert:\n", mdmSignature);
|
|
|
|
CoreUtils.debugLog(log, "Verify Cert:\n", mdmSignature);
|
|
|
|
|
|
|
|
|
|
|
|
URI dcrUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
String accessToken = getAccessToken();
|
|
|
|
.getHttpsPort() + "/dynamic-client-web/register");
|
|
|
|
URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
String dcrContent = "{\n" +
|
|
|
|
.getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios");
|
|
|
|
"\"owner\":\"" + CoreUtils.getUsername() + "\",\n" +
|
|
|
|
Map<String, String> certVerifyHeaders = new HashMap<String, String>();
|
|
|
|
"\"clientName\":\"emm\",\n" +
|
|
|
|
certVerifyHeaders.put("Authorization", "Bearer " + accessToken);
|
|
|
|
"\"grantType\":\"refresh_token password client_credentials\",\n" +
|
|
|
|
certVerifyHeaders.put("Content-Type", "application/json");
|
|
|
|
"\"tokenScope\":\"default\"\n" +
|
|
|
|
String certVerifyContent = "{\n" +
|
|
|
|
|
|
|
|
"\"pem\":\"" + mdmSignature + "\",\n" +
|
|
|
|
|
|
|
|
"\"tenantId\": \"-1234\",\n" +
|
|
|
|
|
|
|
|
"\"serial\":\"\"\n" +
|
|
|
|
"}";
|
|
|
|
"}";
|
|
|
|
Map<String, String> drcHeaders = new HashMap<String, String>();
|
|
|
|
|
|
|
|
drcHeaders.put("Content-Type", "application/json");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null,
|
|
|
|
RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null,
|
|
|
|
null, dcrContent);
|
|
|
|
null, certVerifyContent);
|
|
|
|
CoreUtils.debugLog(log, "DCR response:", response.getContent());
|
|
|
|
CoreUtils.debugLog(log, "Verify response:", response.getContent());
|
|
|
|
JSONObject jsonResponse = new JSONObject(response.getContent());
|
|
|
|
|
|
|
|
String clientId = jsonResponse.getString("client_id");
|
|
|
|
|
|
|
|
String clientSecret = jsonResponse.getString("client_secret");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
URI tokenUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
if (!response.getContent().contains("invalid")) {
|
|
|
|
.getHttpsPort() + "/oauth2/token");
|
|
|
|
return InvocationResponse.CONTINUE;
|
|
|
|
String tokenContent = "grant_type=password&username=" + CoreUtils.getUsername() + "&password=" +
|
|
|
|
}
|
|
|
|
CoreUtils.getPassword() + "&scope=activity-view";
|
|
|
|
log.warn("Unauthorized request for api: " + ctxPath);
|
|
|
|
String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes());
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!"));
|
|
|
|
Map<String, String> tokenHeaders = new HashMap<String, String>();
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
tokenHeaders.put("Authorization", tokenBasicAuth);
|
|
|
|
|
|
|
|
tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null,
|
|
|
|
} else if (headers.containsKey(AuthConstants.PROXY_MUTUAL_AUTH_HEADER)) {
|
|
|
|
null, tokenContent);
|
|
|
|
String subjectDN = headers.get(AuthConstants.PROXY_MUTUAL_AUTH_HEADER).toString();
|
|
|
|
CoreUtils.debugLog(log, "Token response:", response.getContent());
|
|
|
|
CoreUtils.debugLog(log, "Verify subject DN: ", subjectDN);
|
|
|
|
jsonResponse = new JSONObject(response.getContent());
|
|
|
|
String accessToken = getAccessToken();
|
|
|
|
String accessToken = jsonResponse.getString("access_token");
|
|
|
|
URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
|
|
|
|
.getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/android");
|
|
|
|
|
|
|
|
Map<String, String> certVerifyHeaders = new HashMap<String, String>();
|
|
|
|
|
|
|
|
certVerifyHeaders.put("Authorization", "Bearer " + accessToken);
|
|
|
|
|
|
|
|
certVerifyHeaders.put("Content-Type", "application/json");
|
|
|
|
|
|
|
|
String certVerifyContent = "{\n" +
|
|
|
|
|
|
|
|
"\"pem\":\"" + subjectDN + "\",\n" +
|
|
|
|
|
|
|
|
"\"tenantId\": \"-1234\",\n" +
|
|
|
|
|
|
|
|
"\"serial\":\"" + AuthConstants.PROXY_MUTUAL_AUTH_HEADER + "\"\n" +
|
|
|
|
|
|
|
|
"}";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null,
|
|
|
|
|
|
|
|
null, certVerifyContent);
|
|
|
|
|
|
|
|
CoreUtils.debugLog(log, "Verify response:", response.getContent());
|
|
|
|
|
|
|
|
if (!response.getContent().contains("invalid")) {
|
|
|
|
|
|
|
|
return InvocationResponse.CONTINUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
log.warn("Unauthorized request for api: " + ctxPath);
|
|
|
|
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!"));
|
|
|
|
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (headers.containsKey(AuthConstants.ENCODED_PEM)) {
|
|
|
|
|
|
|
|
String encodedPem = headers.get(AuthConstants.ENCODED_PEM).toString();
|
|
|
|
|
|
|
|
CoreUtils.debugLog(log, "Verify Cert:\n", encodedPem);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String accessToken = getAccessToken();
|
|
|
|
URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
.getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios");
|
|
|
|
.getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios");
|
|
|
|
Map<String, String> certVerifyHeaders = new HashMap<String, String>();
|
|
|
|
Map<String, String> certVerifyHeaders = new HashMap<String, String>();
|
|
|
|
certVerifyHeaders.put("Authorization", "Bearer " + accessToken);
|
|
|
|
certVerifyHeaders.put("Authorization", "Bearer " + accessToken);
|
|
|
|
certVerifyHeaders.put("Content-Type", "application/json");
|
|
|
|
certVerifyHeaders.put("Content-Type", "application/json");
|
|
|
|
String certVerifyContent = "{\n" +
|
|
|
|
String certVerifyContent = "{\n" +
|
|
|
|
"\"pem\":\"" + mdmSignature + "\",\n" +
|
|
|
|
"\"pem\":\"" + encodedPem + "\",\n" +
|
|
|
|
"\"tenantId\": \"-1234\",\n" +
|
|
|
|
"\"tenantId\": \"-1234\",\n" +
|
|
|
|
"\"serial\":\"\"\n" +
|
|
|
|
"\"serial\":\"\"\n" +
|
|
|
|
"}";
|
|
|
|
"}";
|
|
|
|
|
|
|
|
|
|
|
|
response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null,
|
|
|
|
RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null,
|
|
|
|
null, certVerifyContent);
|
|
|
|
null, certVerifyContent);
|
|
|
|
CoreUtils.debugLog(log, "Verify response:", response.getContent());
|
|
|
|
CoreUtils.debugLog(log, "Verify response:", response.getContent());
|
|
|
|
|
|
|
|
|
|
|
@ -135,17 +155,16 @@ public class AuthenticationHandler implements Handler {
|
|
|
|
log.warn("Unauthorized request for api: " + ctxPath);
|
|
|
|
log.warn("Unauthorized request for api: " + ctxPath);
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!"));
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!"));
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("Error while processing certificate.", e);
|
|
|
|
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, e);
|
|
|
|
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
log.warn("Unauthorized request for api: " + ctxPath);
|
|
|
|
log.warn("Unauthorized request for api: " + ctxPath);
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required"));
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required"));
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
log.error("Error while processing certificate.", e);
|
|
|
|
|
|
|
|
setFaultCodeAndThrowAxisFault(messageContext, e);
|
|
|
|
|
|
|
|
return InvocationResponse.SUSPEND;
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return InvocationResponse.CONTINUE;
|
|
|
|
return InvocationResponse.CONTINUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -159,7 +178,7 @@ public class AuthenticationHandler implements Handler {
|
|
|
|
* @return boolean
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private boolean isSecuredAPI(MessageContext messageContext) {
|
|
|
|
private boolean isSecuredAPI(MessageContext messageContext) {
|
|
|
|
if (messageContext.getTransportIn() != null &&
|
|
|
|
if (messageContext.getTo() != null && messageContext.getTransportIn() != null &&
|
|
|
|
messageContext.getTransportIn().getName().toLowerCase().equals(AuthConstants.HTTPS)) {
|
|
|
|
messageContext.getTransportIn().getName().toLowerCase().equals(AuthConstants.HTTPS)) {
|
|
|
|
for (String path : apiList) {
|
|
|
|
for (String path : apiList) {
|
|
|
|
if (messageContext.getTo().getAddress().trim().contains(path)) {
|
|
|
|
if (messageContext.getTo().getAddress().trim().contains(path)) {
|
|
|
@ -170,6 +189,55 @@ public class AuthenticationHandler implements Handler {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Get access token to call admin certificate management service for cert validation.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return accessToken String
|
|
|
|
|
|
|
|
* @throws URISyntaxException
|
|
|
|
|
|
|
|
* @throws IOException
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private String getAccessToken() throws URISyntaxException, IOException, JSONException {
|
|
|
|
|
|
|
|
URI dcrUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
|
|
|
|
.getHttpsPort() + "/dynamic-client-web/register");
|
|
|
|
|
|
|
|
String dcrContent = "{\n" +
|
|
|
|
|
|
|
|
"\"owner\":\"" + CoreUtils.getUsername() + "\",\n" +
|
|
|
|
|
|
|
|
"\"clientName\":\"emm\",\n" +
|
|
|
|
|
|
|
|
"\"grantType\":\"refresh_token password client_credentials\",\n" +
|
|
|
|
|
|
|
|
"\"tokenScope\":\"default\"\n" +
|
|
|
|
|
|
|
|
"}";
|
|
|
|
|
|
|
|
Map<String, String> drcHeaders = new HashMap<String, String>();
|
|
|
|
|
|
|
|
drcHeaders.put("Content-Type", "application/json");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null,
|
|
|
|
|
|
|
|
null, dcrContent);
|
|
|
|
|
|
|
|
CoreUtils.debugLog(log, "DCR response:", response.getContent());
|
|
|
|
|
|
|
|
JSONObject jsonResponse = new JSONObject(response.getContent());
|
|
|
|
|
|
|
|
String clientId = jsonResponse.getString("client_id");
|
|
|
|
|
|
|
|
String clientSecret = jsonResponse.getString("client_secret");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
URI tokenUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils
|
|
|
|
|
|
|
|
.getHttpsPort() + "/oauth2/token");
|
|
|
|
|
|
|
|
String tokenContent = "grant_type=password&username=" + CoreUtils.getUsername() + "&password=" +
|
|
|
|
|
|
|
|
CoreUtils.getPassword() + "&scope=activity-view";
|
|
|
|
|
|
|
|
String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes());
|
|
|
|
|
|
|
|
Map<String, String> tokenHeaders = new HashMap<String, String>();
|
|
|
|
|
|
|
|
tokenHeaders.put("Authorization", tokenBasicAuth);
|
|
|
|
|
|
|
|
tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null,
|
|
|
|
|
|
|
|
null, tokenContent);
|
|
|
|
|
|
|
|
CoreUtils.debugLog(log, "Token response:", response.getContent());
|
|
|
|
|
|
|
|
jsonResponse = new JSONObject(response.getContent());
|
|
|
|
|
|
|
|
String accessToken = jsonResponse.getString("access_token");
|
|
|
|
|
|
|
|
return accessToken;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Thow error message to client
|
|
|
|
|
|
|
|
* @param msgContext
|
|
|
|
|
|
|
|
* @param e Exception
|
|
|
|
|
|
|
|
* @throws AxisFault
|
|
|
|
|
|
|
|
*/
|
|
|
|
private void setFaultCodeAndThrowAxisFault(MessageContext msgContext, Exception e) throws AxisFault {
|
|
|
|
private void setFaultCodeAndThrowAxisFault(MessageContext msgContext, Exception e) throws AxisFault {
|
|
|
|
|
|
|
|
|
|
|
|
msgContext.setProperty(AuthConstants.SEC_FAULT, Boolean.TRUE);
|
|
|
|
msgContext.setProperty(AuthConstants.SEC_FAULT, Boolean.TRUE);
|
|
|
|