Handle default authdata in oauth2token handler

fix-access-authorization
Lasantha Dharmakeerthi 9 months ago
commit b204264d05

@ -22,6 +22,8 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager;
import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig;
import io.entgra.device.mgt.core.ui.request.interceptor.beans.AuthData; import io.entgra.device.mgt.core.ui.request.interceptor.beans.AuthData;
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerConstants; import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerConstants;
import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerUtil; import io.entgra.device.mgt.core.ui.request.interceptor.util.HandlerUtil;
@ -31,9 +33,11 @@ import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import io.entgra.device.mgt.core.ui.request.interceptor.beans.ProxyResponse; import io.entgra.device.mgt.core.ui.request.interceptor.beans.ProxyResponse;
import org.apache.http.entity.StringEntity;
import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebServlet;
@ -42,85 +46,53 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.io.IOException; import java.io.IOException;
import java.util.Base64;
@MultipartConfig @MultipartConfig
@WebServlet("/default-oauth2-credentials") @WebServlet("/default-oauth2-credentials")
public class DefaultOauth2TokenHandler extends HttpServlet { public class DefaultOauth2TokenHandler extends HttpServlet {
private static final Log log = LogFactory.getLog(DefaultTokenHandler.class); private static final Log log = LogFactory.getLog(DefaultTokenHandler.class);
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) { protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
try { try {
HttpSession httpSession = req.getSession(false); HttpSession httpSession = req.getSession(false);
if (httpSession != null) { if (httpSession != null) {
AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY); AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
if (authData == null) { if (authData == null) {
HandlerUtil.sendUnAuthorizeResponse(resp); HandlerUtil.sendUnAuthorizeResponse(resp);
return; return;
} }
AuthData defaultAuthData = (AuthData) httpSession AuthData defaultAuthData = (AuthData) httpSession
.getAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY); .getAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY);
if (defaultAuthData != null) { if (defaultAuthData != null) {
HandlerUtil.handleSuccess(resp, constructSuccessProxyResponse(defaultAuthData.getAccessToken())); String accessToken = defaultAuthData.getAccessToken();
return; String accessTokenWithoutPrefix = accessToken.substring(accessToken.indexOf("_") + 1);
}
HttpPost tokenEndpoint = new HttpPost(HandlerUtil.getKeyManagerUrl(req.getScheme()) + HandlerConstants.INTROSPECT_ENDPOINT);
String clientId = authData.getClientId(); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
String clientSecret = authData.getClientSecret(); DeviceManagementConfig dmc = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
String adminUsername = dmc.getKeyManagerConfigurations().getAdminUsername();
String queryString = req.getQueryString(); String adminPassword = dmc.getKeyManagerConfigurations().getAdminPassword();
String scopeString = ""; tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder()
if (StringUtils.isNotEmpty(queryString)) { .encodeToString((adminUsername + HandlerConstants.COLON + adminPassword).getBytes()));
scopeString = req.getParameter("scopes"); StringEntity tokenEPPayload = new StringEntity("token=" + accessTokenWithoutPrefix,
if (scopeString != null) { ContentType.APPLICATION_FORM_URLENCODED);
scopeString = "?scopes=" + scopeString; tokenEndpoint.setEntity(tokenEPPayload);
ProxyResponse tokenStatus = HandlerUtil.execute(tokenEndpoint);
if (HandlerConstants.DEFAULT_TOKEN_IS_EXPIRED.equals(tokenStatus.getData())) {
tokenStatus = HandlerUtil.retryRequestWithRefreshedToken(req, tokenEndpoint, HandlerUtil.getKeyManagerUrl(req.getScheme()), true);
if (!HandlerUtil.isResponseSuccessful(tokenStatus)) {
HandlerUtil.handleError(resp, tokenStatus);
return;
}
} else {
HandlerUtil.handleSuccess(resp, constructSuccessProxyResponse(defaultAuthData.getAccessToken()));
return;
} }
} }
processDefaultTokenRequest(httpSession, authData, req, resp);
String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR
+ System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
String tokenUrl = iotsCoreUrl + "/api/device-mgt/v1.0/devices/" + clientId
+ "/" + clientSecret + "/default-token" + scopeString;
HttpGet defaultTokenRequest = new HttpGet(tokenUrl);
defaultTokenRequest
.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
defaultTokenRequest
.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
ProxyResponse tokenResultResponse = HandlerUtil.execute(defaultTokenRequest);
if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
log.error("Error occurred while invoking the API to get default token data.");
HandlerUtil.handleError(resp, tokenResultResponse);
return;
}
String tokenResult = tokenResultResponse.getData();
if (tokenResult == null) {
log.error("Invalid default token response is received.");
HandlerUtil.handleError(resp, tokenResultResponse);
return;
}
JsonParser jsonParser = new JsonParser();
JsonElement jTokenResult = jsonParser.parse(tokenResult);
if (jTokenResult.isJsonObject()) {
JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject();
AuthData newDefaultAuthData = new AuthData();
newDefaultAuthData.setClientId(clientId);
newDefaultAuthData.setClientSecret(clientSecret);
String defaultToken = jTokenResultAsJsonObject.get("accessToken").getAsString();
newDefaultAuthData.setAccessToken(defaultToken);
newDefaultAuthData.setRefreshToken(jTokenResultAsJsonObject.get("refreshToken").getAsString());
newDefaultAuthData.setScope(jTokenResultAsJsonObject.get("scopes").getAsString());
httpSession.setAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY, newDefaultAuthData);
HandlerUtil.handleSuccess(resp, constructSuccessProxyResponse(defaultToken));
}
} else { } else {
HandlerUtil.sendUnAuthorizeResponse(resp); HandlerUtil.sendUnAuthorizeResponse(resp);
} }
@ -129,6 +101,62 @@ public class DefaultOauth2TokenHandler extends HttpServlet {
} }
} }
private void processDefaultTokenRequest(HttpSession httpSession, AuthData authData, HttpServletRequest req, HttpServletResponse resp) throws IOException {
String clientId = authData.getClientId();
String clientSecret = authData.getClientSecret();
String queryString = req.getQueryString();
String scopeString = "";
if (StringUtils.isNotEmpty(queryString)) {
scopeString = req.getParameter("scopes");
if (scopeString != null) {
scopeString = "?scopes=" + scopeString;
}
}
String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR
+ System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
String tokenUrl = iotsCoreUrl + "/api/device-mgt/v1.0/devices/" + clientId
+ "/" + clientSecret + "/default-token" + scopeString;
HttpGet defaultTokenRequest = new HttpGet(tokenUrl);
defaultTokenRequest
.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
defaultTokenRequest
.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
ProxyResponse tokenResultResponse = HandlerUtil.execute(defaultTokenRequest);
if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
log.error("Error occurred while invoking the API to get default token data.");
HandlerUtil.handleError(resp, tokenResultResponse);
return;
}
String tokenResult = tokenResultResponse.getData();
if (tokenResult == null) {
log.error("Invalid default token response is received.");
HandlerUtil.handleError(resp, tokenResultResponse);
return;
}
JsonParser jsonParser = new JsonParser();
JsonElement jTokenResult = jsonParser.parse(tokenResult);
if (jTokenResult.isJsonObject()) {
JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject();
AuthData newDefaultAuthData = new AuthData();
newDefaultAuthData.setClientId(clientId);
newDefaultAuthData.setClientSecret(clientSecret);
String defaultToken = jTokenResultAsJsonObject.get("accessToken").getAsString();
newDefaultAuthData.setAccessToken(defaultToken);
newDefaultAuthData.setRefreshToken(jTokenResultAsJsonObject.get("refreshToken").getAsString());
newDefaultAuthData.setScope(jTokenResultAsJsonObject.get("scopes").getAsString());
httpSession.setAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY, newDefaultAuthData);
HandlerUtil.handleSuccess(resp, constructSuccessProxyResponse(defaultToken));
}
}
/** /**
* Get Success Proxy Response * Get Success Proxy Response
* @param defaultAccessToken Access token which has default scope * @param defaultAccessToken Access token which has default scope

@ -52,6 +52,7 @@ public class HandlerConstants {
public static final String API_COMMON_CONTEXT = "/api"; public static final String API_COMMON_CONTEXT = "/api";
public static final String EXECUTOR_EXCEPTION_PREFIX = "ExecutorException-"; public static final String EXECUTOR_EXCEPTION_PREFIX = "ExecutorException-";
public static final String TOKEN_IS_EXPIRED = "ACCESS_TOKEN_IS_EXPIRED"; public static final String TOKEN_IS_EXPIRED = "ACCESS_TOKEN_IS_EXPIRED";
public static final String DEFAULT_TOKEN_IS_EXPIRED = "{\"active\":false}";
public static final String REPORTS = "Reports"; public static final String REPORTS = "Reports";
public static final String APP_NAME = "App-Name"; public static final String APP_NAME = "App-Name";
public static final String[] SSO_LOGOUT_COOKIE_PATHS = new String[]{"/", "/entgra-ui-request-handler", public static final String[] SSO_LOGOUT_COOKIE_PATHS = new String[]{"/", "/entgra-ui-request-handler",

@ -73,6 +73,7 @@ import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Base64;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
@ -613,26 +614,32 @@ public class HandlerUtil {
* @throws IOException If an error occurs when try to retry the request. * @throws IOException If an error occurs when try to retry the request.
*/ */
public static ProxyResponse retryRequestWithRefreshedToken(HttpServletRequest req, HttpRequestBase httpRequest, public static ProxyResponse retryRequestWithRefreshedToken(HttpServletRequest req, HttpRequestBase httpRequest,
String apiEndpoint) throws IOException { String apiEndpoint, boolean isDefaultAuthToken) throws IOException {
ProxyResponse retryResponse = refreshToken(req, apiEndpoint); ProxyResponse retryResponse = refreshToken(req, apiEndpoint, isDefaultAuthToken);
if (isResponseSuccessful(retryResponse)) { if (isResponseSuccessful(retryResponse)) {
HttpSession session = req.getSession(false); HttpSession session = req.getSession(false);
if (session == null) { if (session == null) {
log.error("Unauthorized, You are not logged in. Please log in to the portal"); log.error("Unauthorized, You are not logged in. Please log in to the portal");
return constructProxyResponseByErrorCode(HttpStatus.SC_UNAUTHORIZED); return constructProxyResponseByErrorCode(HttpStatus.SC_UNAUTHORIZED);
} }
httpRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken()); if (!isDefaultAuthToken) {
ProxyResponse proxyResponse = HandlerUtil.execute(httpRequest); httpRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { ProxyResponse proxyResponse = HandlerUtil.execute(httpRequest);
log.error("Error occurred while invoking the API after refreshing the token."); if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
log.error("Error occurred while invoking the API after refreshing the token.");
return proxyResponse;
}
return proxyResponse; return proxyResponse;
} }
return proxyResponse;
} }
return retryResponse; return retryResponse;
} }
public static ProxyResponse retryRequestWithRefreshedToken(HttpServletRequest req, HttpRequestBase httpRequest,
String apiEndpoint) throws IOException {
return retryRequestWithRefreshedToken(req, httpRequest, apiEndpoint, false);
}
/*** /***
* This method is responsible to get the refresh token * This method is responsible to get the refresh token
* *
@ -640,7 +647,7 @@ public class HandlerUtil {
* @return If successfully renew tokens, returns TRUE otherwise return FALSE * @return If successfully renew tokens, returns TRUE otherwise return FALSE
* @throws IOException If an error occurs while witting error response to client side or invoke token renewal API * @throws IOException If an error occurs while witting error response to client side or invoke token renewal API
*/ */
private static ProxyResponse refreshToken(HttpServletRequest req, String keymanagerUrl) private static ProxyResponse refreshToken(HttpServletRequest req, String keymanagerUrl, boolean isDefaultAuthToken)
throws IOException { throws IOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("refreshing the token"); log.debug("refreshing the token");
@ -653,8 +660,11 @@ public class HandlerUtil {
// handleError(resp, HttpStatus.SC_UNAUTHORIZED); // handleError(resp, HttpStatus.SC_UNAUTHORIZED);
return tokenResultResponse; return tokenResultResponse;
} }
if (isDefaultAuthToken) {
authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY); authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY);
} else {
authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
}
tokenResultResponse = getTokenResult(authData, keymanagerUrl); tokenResultResponse = getTokenResult(authData, keymanagerUrl);
if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
log.error("Error occurred while refreshing access token."); log.error("Error occurred while refreshing access token.");
@ -666,7 +676,11 @@ public class HandlerUtil {
JsonElement jTokenResult = jsonParser.parse(tokenResultResponse.getData()); JsonElement jTokenResult = jsonParser.parse(tokenResultResponse.getData());
if (jTokenResult.isJsonObject()) { if (jTokenResult.isJsonObject()) {
setNewAuthData(constructAuthDataFromTokenResult(jTokenResult, authData), session); if (isDefaultAuthToken) {
setNewDefaultAuthData(constructAuthDataFromTokenResult(jTokenResult, authData), session);
} else {
setNewAuthData(constructAuthDataFromTokenResult(jTokenResult, authData), session);
}
return tokenResultResponse; return tokenResultResponse;
} }
@ -675,6 +689,11 @@ public class HandlerUtil {
// handleError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR); // handleError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR);
return tokenResultResponse; return tokenResultResponse;
} }
private static ProxyResponse refreshToken(HttpServletRequest req, String keymanagerUrl) throws IOException {
return refreshToken(req, keymanagerUrl, false);
}
public static ProxyResponse getTokenResult(AuthData authData, String keymanagerUrl) throws IOException { public static ProxyResponse getTokenResult(AuthData authData, String keymanagerUrl) throws IOException {
HttpPost tokenEndpoint = new HttpPost(keymanagerUrl + HandlerConstants.OAUTH2_TOKEN_ENDPOINT); HttpPost tokenEndpoint = new HttpPost(keymanagerUrl + HandlerConstants.OAUTH2_TOKEN_ENDPOINT);
StringEntity tokenEndpointPayload = new StringEntity( StringEntity tokenEndpointPayload = new StringEntity(
@ -683,6 +702,12 @@ public class HandlerUtil {
tokenEndpoint.setEntity(tokenEndpointPayload); tokenEndpoint.setEntity(tokenEndpointPayload);
String encodedClientApp = authData.getEncodedClientApp(); String encodedClientApp = authData.getEncodedClientApp();
if (encodedClientApp == null) {
String clientId = authData.getClientId();
String clientSecret = authData.getClientSecret();
String toEncode = clientId + ":" + clientSecret;
encodedClientApp = Base64.getEncoder().encodeToString(toEncode.getBytes());
}
tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC +
encodedClientApp); encodedClientApp);
tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
@ -694,6 +719,11 @@ public class HandlerUtil {
session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, newAuthData); session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, newAuthData);
} }
public static void setNewDefaultAuthData(AuthData newAuthData, HttpSession session) {
authData = newAuthData;
session.setAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY, newAuthData);
}
public static AuthData constructAuthDataFromTokenResult(JsonElement tokenResult, AuthData authData) { public static AuthData constructAuthDataFromTokenResult(JsonElement tokenResult, AuthData authData) {
JsonObject jTokenResultAsJsonObject = tokenResult.getAsJsonObject(); JsonObject jTokenResultAsJsonObject = tokenResult.getAsJsonObject();
AuthData newAuthData = new AuthData(); AuthData newAuthData = new AuthData();

Loading…
Cancel
Save