Fixed getRoles refs #22754

This commit is contained in:
Luca Frosini 2022-01-31 15:47:02 +01:00
parent 464515262f
commit 6c9dd41851
1 changed files with 45 additions and 15 deletions

View File

@ -1,12 +1,15 @@
package org.gcube.common.authorization.utils.secret; package org.gcube.common.authorization.utils.secret;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
@ -19,6 +22,7 @@ import org.gcube.common.authorization.utils.user.KeycloakUser;
import org.gcube.common.authorization.utils.user.User; import org.gcube.common.authorization.utils.user.User;
import org.gcube.common.keycloak.KeycloakClientFactory; import org.gcube.common.keycloak.KeycloakClientFactory;
import org.gcube.common.keycloak.model.AccessToken; import org.gcube.common.keycloak.model.AccessToken;
import org.gcube.common.keycloak.model.AccessToken.Access;
import org.gcube.common.keycloak.model.ModelUtils; import org.gcube.common.keycloak.model.ModelUtils;
import org.gcube.common.keycloak.model.RefreshToken; import org.gcube.common.keycloak.model.RefreshToken;
import org.gcube.common.keycloak.model.TokenResponse; import org.gcube.common.keycloak.model.TokenResponse;
@ -44,6 +48,10 @@ public class JWTSecret extends Secret {
protected AccessToken accessToken; protected AccessToken accessToken;
protected TokenResponse tokenResponse; protected TokenResponse tokenResponse;
protected RenewalProvider renewalProvider; protected RenewalProvider renewalProvider;
protected Set<String> roles;
protected ClientInfo clientInfo;
protected Caller caller;
protected String context;
public JWTSecret(String token) { public JWTSecret(String token) {
super(10, token); super(10, token);
@ -105,37 +113,58 @@ public class JWTSecret extends Secret {
} }
return accessToken; return accessToken;
} }
protected Set<String> getRoles() throws Exception{
if(roles == null) {
Map<String,Access> accesses = getAccessToken().getResourceAccess();
String context = getContext();
Access access = accesses.get(URLEncoder.encode(context, StandardCharsets.UTF_8.toString()));
if(access != null) {
roles = access.getRoles();
}else {
roles = new HashSet<>();
}
}
return roles;
}
@Override @Override
public ClientInfo getClientInfo() throws Exception { public ClientInfo getClientInfo() throws Exception {
getAccessToken(); if(clientInfo==null) {
List<String> roles = new ArrayList<>(accessToken.getRealmAccess().getRoles()); getAccessToken();
ClientInfo clientInfo = new UserInfo(accessToken.getPreferredUsername(), roles, accessToken.getEmail(), accessToken.getGivenName(), accessToken.getFamilyName()); List<String> roles = new ArrayList<>(getRoles());
clientInfo = new UserInfo(accessToken.getPreferredUsername(), roles, accessToken.getEmail(), accessToken.getGivenName(), accessToken.getFamilyName());
}
return clientInfo; return clientInfo;
} }
@Override @Override
public Caller getCaller() throws Exception { public Caller getCaller() throws Exception {
Caller caller = new Caller(getClientInfo(), "token"); if(caller==null) {
caller = new Caller(getClientInfo(), "token");
}
return caller; return caller;
} }
@Override @Override
public String getContext() throws Exception { public String getContext() throws Exception {
String context = null; if(context==null) {
String[] audience = getAccessToken().getAudience(); String[] audience = getAccessToken().getAudience();
for (String aud : audience) { for (String aud : audience) {
if (aud != null && aud.compareTo("") != 0) { if (aud != null && aud.compareTo("") != 0) {
try { try {
context = URLDecoder.decode(context, StandardCharsets.UTF_8.toString()); String contextToBeValidated = URLDecoder.decode(aud, StandardCharsets.UTF_8.toString());
ScopeBean scopeBean = new ScopeBean(context); ScopeBean scopeBean = new ScopeBean(contextToBeValidated);
return scopeBean.toString(); context = scopeBean.toString();
} catch (Exception e) { return context;
logger.error("Invalid context name for audience {} in access token. Trying next one if any.", aud, e); } catch (Exception e) {
logger.error("Invalid context name for audience {} in access token. Trying next one if any.", aud, e);
}
} }
} }
throw new Exception("Invalid context in access token");
} }
throw new Exception("Invalid context in access token"); return context;
} }
@Override @Override
@ -187,6 +216,7 @@ public class JWTSecret extends Secret {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
String accessTokenString = objectMapper.writeValueAsString(accessToken); String accessTokenString = objectMapper.writeValueAsString(accessToken);
user = objectMapper.readValue(accessTokenString, KeycloakUser.class); user = objectMapper.readValue(accessTokenString, KeycloakUser.class);
user.setRoles(getRoles());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(); throw new RuntimeException();
} }