package com.nubisware.oidc.rest; import java.io.Serializable; import java.util.ArrayList; import java.util.Base64; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.nubisware.oidc.keycloak.KeycloakHelper; public class JWTToken implements Serializable { protected static Logger logger = LoggerFactory.getLogger(KeycloakHelper.class); private static final long serialVersionUID = -7063122428186284827L; private static String SHARE_PREFIX = "USER_"; public static String OIDC_TOKEN_ATTRIBUTE = SHARE_PREFIX + "OIDC_JWT"; public static String RPT_TOKEN_ATTRIBUTE = SHARE_PREFIX + "UMA_RPT_JWT"; public static final String ACCOUNT_RESOURCE = "account"; private String raw; private JSONObject token; private JSONObject identity; public static JWTToken fromString(String tokenString) { if (tokenString == null) { return null; } try { return new JWTToken(tokenString); } catch (ParseException e) { return null; } } private JWTToken(String raw) throws ParseException { this.raw = raw; this.parse(); } private void parse() throws ParseException { token = (JSONObject) new JSONParser().parse(this.raw); String[] parts = getAccessTokenString().split("\\."); identity = (JSONObject) new JSONParser().parse(new String(Base64.getDecoder().decode(parts[1]))); } public String getRaw() { return raw; } public String getAccessTokenString() { return (String) token.get("access_token"); } public String getRefreshTokenString() { return (String) token.get("refresh_token"); } public String getAsBearer() { return "Bearer " + getAccessTokenString(); } public JSONObject getIdentity() { return identity; } public String getExp() { return (String) getIdentity().get("exp"); } public Date getExpAsDate() { return new Date(Long.getLong(getExp()) * 1000); } public Calendar getExpAsCalendar() { Calendar cal = Calendar.getInstance(); cal.setTime(getExpAsDate()); return cal; } public boolean isExpired() { return new Date().after(getExpAsDate()); } public String getSub() { return (String) getIdentity().get("sub"); } public String getEmail() { return (String) getIdentity().get("email"); } public String getFamily() { return (String) getIdentity().get("family_name"); } public String getGiven() { return (String) getIdentity().get("given_name"); } public String getUserName() { return (String) getIdentity().get("preferred_username"); } public String getDisplayName() { return (String) getIdentity().get("name"); } protected JSONObject getResourceAccess() { return (JSONObject) getIdentity().get("resource_access"); } @SuppressWarnings("unchecked") protected Iterator getResourceAccessKeys() { return getResourceAccess().keySet().iterator(); } public List getResourceAccessRoles(String resource) { JSONArray rolesJsonArray = (JSONArray) ((JSONObject) getResourceAccess().get(resource)) .get("roles"); List roles = new ArrayList<>(rolesJsonArray.size()); for (int i = 0; i < rolesJsonArray.size(); i++) { roles.add((String) rolesJsonArray.get(i)); } return roles; } public Map> getResourceNameToAccessRolesMap(List resourcesToSkip) { Map> map = new HashMap<>(); Iterator resourcesIterator = getResourceAccessKeys(); while (resourcesIterator.hasNext()) { String resource = resourcesIterator.next(); if (resourcesToSkip.contains(resource)) { continue; } map.put(resource, getResourceAccessRoles(resource)); } return map; } /* "authorization": { "permissions": [ { "rsid": "e9afce09-baeb-4569-8e9a-67342ce39cf5", "rsname": "a", "resource_scopes" : [] } ] } */ protected JSONArray getAuthorizationPermissions() { JSONObject authorization = (JSONObject) getIdentity().get("authorization"); return (JSONArray) authorization.get("permissions"); } public List getAuthorizationPermissionRSNames() { List permissionsRSName = new ArrayList<>(); JSONArray permissions = getAuthorizationPermissions(); for (int i = 0; i < permissions.size(); i++) { JSONObject permissionsEntry = (JSONObject) permissions.get(i); permissionsRSName.add((String) permissionsEntry.get("rsname")); } return permissionsRSName; } public List getAuthorizationPermissionRSNameResourceScopes(String rsname) { List scopes = new ArrayList<>(); JSONArray permissions = getAuthorizationPermissions(); for (int i = 0; i < permissions.size(); i++) { JSONObject permissionsEntry = (JSONObject) permissions.get(i); if (rsname.equals(permissionsEntry.get("rsname"))) { JSONArray scopesJsonArray = (JSONArray) permissionsEntry.get("resource_scopes"); if (scopesJsonArray != null) { for (int j = 0; j < scopesJsonArray.size(); j++) { scopes.add((String) scopesJsonArray.get(j)); } } } } return scopes; } public Map> getAuthorizationPermissionRSNameToResourceScopesMap() { Map> map = new HashMap<>(); for (String aprn : getAuthorizationPermissionRSNames() ) { map.put(aprn, getAuthorizationPermissionRSNameResourceScopes(aprn)); } return map; } }