blob: f3a550a35d8fa3ecbf6e5cccbeac8ed02d8fde79 [file] [log] [blame]
/**
******************************************************************************
* Copyright © 2017-2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
******************************************************************************
*/
package org.eclipse.openk.portal.auth2.util;
import java.nio.charset.StandardCharsets;
import javax.ws.rs.core.MediaType;
import org.eclipse.openk.portal.auth2.model.JwtHeader;
import org.eclipse.openk.portal.auth2.model.JwtPayload;
import org.eclipse.openk.portal.auth2.model.JwtToken;
import org.eclipse.openk.portal.auth2.model.KeyCloakRole;
import org.eclipse.openk.portal.auth2.model.KeyCloakUser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.openk.portal.common.BackendConfig;
import org.eclipse.openk.portal.common.JsonGeneratorBase;
import org.eclipse.openk.portal.exceptions.PortalInternalServerError;
import org.keycloak.common.util.Base64Url;
public class JwtHelper {
private static final Logger logger = Logger.getLogger(JwtHelper.class.getName());
private JwtHelper() {
}
public static JwtToken login(String user, String password) throws PortalInternalServerError {
String token = sendPost(BackendConfig.getInstance().getAuthServerUrl() + "auth/realms/" +
BackendConfig.getInstance().getKeycloakRealm() + "/protocol/openid-connect/token",
"username=" + user + "&password=" + password + "&client_id="
+ BackendConfig.getInstance().getKeycloakClient() + "&grant_type=password");
return getJwtTokenFromJson(token);
}
public static boolean serviceAvailable() throws PortalInternalServerError {
String jsonRet = sendGet(BackendConfig.getInstance().getAuthServerUrl() + "auth/realms/" +
BackendConfig.getInstance().getKeycloakRealm(), "", null);
return jsonRet.contains("realm") && jsonRet.contains(BackendConfig.getInstance().getKeycloakRealm());
}
public static List<KeyCloakUser> getUsers(JwtToken jwtToken, int maxUsers) throws PortalInternalServerError {
String users = sendGet(BackendConfig.getInstance().getAuthServerUrl() + "auth/admin/realms/" + BackendConfig.getInstance().getKeycloakRealm() + "/users?max="+maxUsers,
MediaType.APPLICATION_JSON, jwtToken.getAccessToken());
return getUserListFromJson(users);
}
public static List<KeyCloakRole> getRolesForUser(JwtToken jwtToken, String id) throws PortalInternalServerError {
String roles = sendGet(BackendConfig.getInstance().getAuthServerUrl() + "auth/admin/realms/" + BackendConfig.getInstance().getKeycloakRealm() + "/users/" + id + "/role-mappings/realm",
MediaType.APPLICATION_JSON, jwtToken.getAccessToken());
return getRolesListFromJson(roles);
}
public static JwtHeader getJwtHeaderFromJson(String json) {
return JsonGeneratorBase.getGson().fromJson(json, JwtHeader.class);
}
public static JwtPayload getJwtPayloadFromJson(String json) {
return JsonGeneratorBase.getGson().fromJson(json, JwtPayload.class);
}
public static JwtToken getJwtTokenFromJson(String json) {
return JsonGeneratorBase.getGson().fromJson(json, JwtToken.class);
}
public static List<KeyCloakUser> getUserListFromJson(String json) throws PortalInternalServerError {
try {
Type listType = new TypeToken<List<KeyCloakUser>>() {
}.getType();
return JsonGeneratorBase.getGson().fromJson(json, listType);
} catch (JsonSyntaxException ex) {
logger.error("Error in getUserListFromJson", ex);
throw new PortalInternalServerError("JsonSyntaxException");
}
}
public static List<KeyCloakRole> getRolesListFromJson(String json) throws PortalInternalServerError {
try {
Type listType = new TypeToken<List<KeyCloakRole>>() {
}.getType();
return JsonGeneratorBase.getGson().fromJson(json, listType);
} catch (JsonSyntaxException ex) {
logger.error("Error in getRolesListFromJson", ex);
throw new PortalInternalServerError("JsonSyntaxException");
}
}
public static JwtPayload getPayLoad(JwtToken token) {
String[] parts = token.getAccessToken().split("[.]");
//parts[0] is the jwtHeader
String jwtPayload = parts[1];
//parts[2] is the jwtVerifySignature
// decode
byte[] decoded = Base64Url.decode(jwtPayload);
jwtPayload = new String(decoded, StandardCharsets.UTF_8);
logger.info(jwtPayload);
return getJwtPayloadFromJson(jwtPayload);
}
private static HttpURLConnection getHttpConnection(String targetUrl) throws PortalInternalServerError {
try {
URL url = new URL(targetUrl);
return (HttpURLConnection) url.openConnection();
} catch (IOException e) {
logger.error(e);
throw new PortalInternalServerError("HttpURLConnection IOException");
}
}
private static String sendGet(String targetUrl, String accept, String token) throws PortalInternalServerError {
logger.info("sendGet");
HttpURLConnection con = getHttpConnection(targetUrl);
StringBuilder response = new StringBuilder(); // or StringBuffer if Java version 5+
try (AutoCloseable conc = con::disconnect) {
con.setRequestMethod("GET");
con.setRequestProperty("Accept", accept);
con.setInstanceFollowRedirects(false);
if (token != null) // is authenticated
{
con.setRequestProperty("Authorization", "Bearer " + token);
}
InputStream is = con.getInputStream();
try (BufferedReader rd = new BufferedReader(new InputStreamReader(is))) {
String line;
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
logger.info("Got line -> " + line);
}
}
logger.info("sendGet was successful");
return response.toString();
} catch (Exception e) {
logger.error("Error occured in sendGet: " + e);
return null;
}
}
private static String sendPost(String targetUrl, String urlParameters) throws PortalInternalServerError {
logger.info("sendPost");
HttpURLConnection con = getHttpConnection(targetUrl);
StringBuilder response = new StringBuilder(); // or StringBuffer if Java version 5+
try (AutoCloseable conc = con::disconnect) {
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Accept", MediaType.APPLICATION_JSON);
con.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
con.setInstanceFollowRedirects(false);
con.setDoOutput(true);
// Send request
try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
wr.writeBytes(urlParameters);
}
// Get Response
InputStream is = con.getInputStream();
try (BufferedReader rd = new BufferedReader(new InputStreamReader(is))) {
String line;
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
}
return response.toString();
} catch (Exception e) {
logger.error("Error occured in sendPost: " + e);
return null;
}
}
public static String formatToken(String accessToken) {
return accessToken != null ? accessToken.replace("Bearer", "").trim() : "";
}
}