Skip to content

Commit

Permalink
feat(jans-keycloak-integration): enhancements to jans-keycloak-integr…
Browse files Browse the repository at this point in the history
…ation #8614

Signed-off-by: Rolain Djeumen <uprightech@gmail.com>
  • Loading branch information
uprightech committed Jun 24, 2024
1 parent b571739 commit 1a1de0f
Show file tree
Hide file tree
Showing 17 changed files with 75 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static void main(String[] args) throws InterruptedException, ParserCreate
return;
}catch(InterruptedException e) {
log.error("Application interrupted",e);
throw e;
System.exit(-1);
}catch(Exception e) {
log.error("Fatal error starting application",e);
if(jobScheduler != null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import org.keycloak.models.ClientModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.SubjectCredentialManager;
Expand All @@ -33,7 +32,7 @@ public class JansUserModel implements UserModel {
private final JansPerson jansPerson;
private final StorageId storageId;

public JansUserModel(KeycloakSession session, ComponentModel storageProviderModel, JansPerson jansPerson) {
public JansUserModel(ComponentModel storageProviderModel, JansPerson jansPerson) {

this.jansPerson = jansPerson;
String userId = jansPerson.customAttributeValue(INUM_ATTR_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private List<String> convertToString(List<Object> values) {
List<String> ret = new ArrayList<>();
for(Object val : values) {
if(val instanceof String strval) {
ret.add((String) strval);
ret.add(strval);
}else {
ret.add(val.toString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ private void addIssuerCacheEntry(String issuer,String key, Object value) {

private void performHouseCleaning() {

for(String issuer: cacheEntries.keySet()) {
Map<String,CacheEntry> issuerCache = cacheEntries.get(issuer);
for(Map.Entry<String,CacheEntry> entry : issuerCache.entrySet()) {
if(entry.getValue().isExpired()) {
issuerCache.remove(entry.getKey());
for(Map.Entry<String,Map<String,CacheEntry>> cacheEntry: cacheEntries.entrySet()) {
Map<String,CacheEntry> issuerCache = cacheEntries.get(cacheEntry.getKey());
for(Map.Entry<String,CacheEntry> issuerEntry : issuerCache.entrySet()) {
if(issuerEntry.getValue().isExpired()) {
issuerCache.remove(issuerEntry.getKey());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ public NimbusOIDCRefreshToken(RefreshToken refreshToken) {
this.refreshToken = refreshToken;
}

private RefreshToken refreshTokenRef() {

return this.refreshToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,10 @@
import java.net.URISyntaxException;
import java.util.List;

import org.jboss.logging.Logger;

public class NimbusOIDCService implements OIDCService {

private static final Logger log = Logger.getLogger(NimbusOIDCService.class);


private OIDCMetaCache metaCache;

public NimbusOIDCService(OIDCMetaCache metaCache) {
Expand Down Expand Up @@ -134,8 +132,8 @@ public OIDCUserInfoResponse requestUserInfo(String issuerUrl, OIDCAccessToken ac

BearerAccessToken bearertoken = ((NimbusOIDCAccessToken) accesstoken).asBearerToken();
try {
HTTPResponse http_response = new UserInfoRequest(getUserInfoEndpoint(issuerUrl),bearertoken).toHTTPRequest().send();
UserInfoResponse userinforesponse = UserInfoResponse.parse(http_response);
HTTPResponse httpResponse = new UserInfoRequest(getUserInfoEndpoint(issuerUrl),bearertoken).toHTTPRequest().send();
UserInfoResponse userinforesponse = UserInfoResponse.parse(httpResponse);
return new NimbusOIDCUserInfoResponse(userinforesponse);
} catch (IOException e) {
throw new OIDCUserInfoRequestError("I/O error trying to obtain user info",e);
Expand Down Expand Up @@ -205,9 +203,7 @@ private OIDCProviderMetadata obtainMetadataFromServer(String issuerUrl) throws O
try {
Issuer issuer = new Issuer(issuerUrl);
return OIDCProviderMetadata.resolve(issuer);
}catch(GeneralException e) {
throw new OIDCMetaError("Could not obtain metadata from server",e);
}catch(IOException e) {
}catch(GeneralException | IOException e) {
throw new OIDCMetaError("Could not obtain metadata from server",e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ public NimbusOIDCTokenResponse(TokenResponse tokenResponse) {
Tokens tokens = atresponse.getTokens();
this.accessToken = new NimbusOIDCAccessToken(tokens.getAccessToken());
this.refreshToken = new NimbusOIDCRefreshToken(tokens.getRefreshToken());
}else {

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ public class ProviderIDs {
public static final String JANS_SAML_USER_ATTRIBUTE_MAPPER_PROVIDER = "kc-jans-saml-user-attribute-mapper";
public static final String JANS_DEFAULT_THIN_BRIDGE_PROVIDER = "kc-jans-thin-bridge-default";
public static final String JANS_USER_STORAGE_PROVIDER = "kc-jans-user-storage";

private ProviderIDs() {
//private constructor
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;

import java.security.SecureRandom;
import java.text.MessageFormat;

import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -101,6 +98,10 @@ public void authenticate(AuthenticationFlowContext context) {
log.errorv(e,"OIDC Error obtaining the authorization url");
Response response = context.form().createForm(JANS_AUTH_ERROR_FTL);
context.failure(AuthenticationFlowError.INTERNAL_ERROR,response);
}catch(NullPointerException e) {
log.errorv(e,"NullPointerException obtaining the authorization url");
Response response = context.form().createForm(JANS_AUTH_ERROR_FTL);
context.failure(AuthenticationFlowError.INTERNAL_ERROR,response);
}
}

Expand All @@ -113,14 +114,14 @@ public void action(AuthenticationFlowContext context) {
return;
}

String openid_code = getOpenIdCode(context);
if(openid_code == null) {
String openidCode = getOpenIdCode(context);
if(openidCode == null) {
log.errorv("Missing authentication code during response processing");
context.failure(AuthenticationFlowError.INTERNAL_ERROR,onMissingAuthenticationCode(context));
return;
}

OIDCTokenRequest tokenrequest = createTokenRequest(config, openid_code, createRedirectUri(context));
OIDCTokenRequest tokenrequest = createTokenRequest(config, openidCode, createRedirectUri(context));
try {
OIDCTokenResponse tokenresponse = oidcService.requestTokens(config.normalizedIssuerUrl(), tokenrequest);
if(!tokenresponse.indicatesSuccess()) {
Expand Down Expand Up @@ -170,20 +171,19 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode

@Override
public void setRequiredActions(KeycloakSession session, RealmModel model, UserModel user) {

return;
//for now no required actions to specify
}

@Override
public List<RequiredActionFactory> getRequiredActions(KeycloakSession session) {

return null;
return new ArrayList<>();
}

@Override
public void close() {

return;
// nothing to do for now when then authenticator is shutdown
}

private Configuration extractAndValidateConfiguration(AuthenticationFlowContext context) {
Expand Down Expand Up @@ -230,7 +230,7 @@ private UserModel findUserByNameOrEmail(AuthenticationFlowContext context, Strin

private Map<String,String> parseQueryParameters(String params) {

Map<String,String> ret = new HashMap<String,String>();
Map<String,String> ret = new HashMap<>();
if(params == null) {
return ret;
}
Expand Down Expand Up @@ -260,20 +260,20 @@ private Configuration pluginConfigurationFromContext(AuthenticationFlowContext c
return null;
}

String server_url = config.getConfig().get(JansAuthenticatorConfigProp.SERVER_URL.getName());
String client_id = config.getConfig().get(JansAuthenticatorConfigProp.CLIENT_ID.getName());
String client_secret = config.getConfig().get(JansAuthenticatorConfigProp.CLIENT_SECRET.getName());
String serverUrl = config.getConfig().get(JansAuthenticatorConfigProp.SERVER_URL.getName());
String clientId = config.getConfig().get(JansAuthenticatorConfigProp.CLIENT_ID.getName());
String clientSecret = config.getConfig().get(JansAuthenticatorConfigProp.CLIENT_SECRET.getName());
String issuer = config.getConfig().get(JansAuthenticatorConfigProp.ISSUER.getName());
String extra_scopes = config.getConfig().get(JansAuthenticatorConfigProp.EXTRA_SCOPES.getName());
List<String> parsed_extra_scopes = new ArrayList<>();
if(extra_scopes != null) {
String [] tokens = extra_scopes.split(",");
String extraScopes = config.getConfig().get(JansAuthenticatorConfigProp.EXTRA_SCOPES.getName());
List<String> parsedExtraScopes = new ArrayList<>();
if(extraScopes != null) {
String [] tokens = extraScopes.split(",");
for(String token : tokens) {
parsed_extra_scopes.add(token.trim());
parsedExtraScopes.add(token.trim());
}
}

return new Configuration(server_url,client_id,client_secret,issuer,parsed_extra_scopes);
return new Configuration(serverUrl,clientId,clientSecret,issuer,parsedExtraScopes);
}

private final String generateOIDCState() {
Expand Down Expand Up @@ -364,7 +364,7 @@ public static class ValidationResult {
public void addError(String error) {

if(errors == null) {
this.errors = new ArrayList<String>();
this.errors = new ArrayList<>();
}
this.errors.add(error);
}
Expand Down Expand Up @@ -418,18 +418,18 @@ public ValidationResult validate() {

public String normalizedIssuerUrl() {

String effective_url = issuerUrl;
if(effective_url == null) {
effective_url = serverUrl;
String effectiveUrl = issuerUrl;
if(effectiveUrl == null) {
effectiveUrl = serverUrl;
}
if(effective_url == null) {
if(effectiveUrl == null) {
return null;
}

if(effective_url.charAt(effective_url.length() -1) == '/') {
return effective_url.substring(0, effective_url.length() -1);
if(effectiveUrl.charAt(effectiveUrl.length() -1) == '/') {
return effectiveUrl.substring(0, effectiveUrl.length() -1);
}
return effective_url;
return effectiveUrl;
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@ public Authenticator create(KeycloakSession session) {
@Override
public void init(Config.Scope config) {

return;
//nothing to do for now during initialization
}

@Override
public void close() {

return;
//nothing to do for now during shutdown
}

@Override
public void postInit(KeycloakSessionFactory factory) {

return;
//nothing to do postInit
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public class SessionAttributes {
public static final String KC_ACTION_URI = "kc.action-uri";
public static final String JANS_OIDC_CODE = "jans.oidc.code";
public static final String JANS_SESSION_STATE = "jans.session.state";

private SessionAttributes() {
//private constructor
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.jans.kc.model.JansUserAttributeModel;
import io.jans.kc.model.internal.JansPerson;
import io.jans.kc.spi.custom.JansThinBridgeProvider;
import io.jans.kc.spi.custom.JansThinBridgeInitException;
import io.jans.kc.spi.custom.JansThinBridgeOperationException;

import io.jans.model.JansAttribute;
Expand Down Expand Up @@ -37,7 +36,7 @@ public DefaultJansThinBridgeProvider(final PersistenceEntryManager persistenceEn

@Override
public void close() {

//for now , nothing to do during the close of the provider
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import io.jans.kc.spi.custom.JansThinBridgeProviderFactory;
import io.jans.kc.spi.ProviderIDs;
import io.jans.kc.spi.custom.JansThinBridgeInitException;
import io.jans.kc.spi.custom.JansThinBridgeInitException;
import io.jans.orm.model.PersistenceConfiguration;
import io.jans.orm.PersistenceEntryManager;
import io.jans.orm.PersistenceEntryManagerFactory;
Expand Down Expand Up @@ -75,19 +74,17 @@ public JansThinBridgeProvider create(KeycloakSession session) {

@Override
public void init(Config.Scope config) {


//nothing to do during init for now
}

@Override
public void postInit(KeycloakSessionFactory factory) {

//nothing to do during postInit for now
}

@Override
public void close() {


//nothing to do during cost for now
}

@Override
Expand All @@ -96,32 +93,6 @@ public String getId() {
return PROVIDER_ID;
}



private final FileConfiguration loadBaseConfiguration(final String filename) {

try {
return new FileConfiguration(filename);
}catch(Exception e) {
log.errorv(e,"Failed to load configuration from {0}",filename);
final String errordesc = (filename != null ? " from file " + filename : ". Invalid filename specified");
throw new JansThinBridgeInitException("Failed to load configuration" + errordesc);
}
}

private final StringEncrypter createStringEncrypterFromSaltFile(final String path) {

try {
final String salt = cryptographicSaltFromFile(path);
if(StringUtils.isEmpty(salt)) {
return null;
}
return StringEncrypter.instance(salt);
}catch(StringEncrypter.EncryptionException e) {
throw new JansThinBridgeInitException("Failed to create string encrypted",e);
}
}

private final String cryptographicSaltFromFile(final String path) {

FileConfiguration cryptoconfig = new FileConfiguration(path);
Expand All @@ -132,7 +103,7 @@ private final Properties preparePersistenceProperties(final PersistenceConfigura

try {
FileConfiguration config = persistenceConfiguration.getConfiguration();
Properties connprops = (Properties) config.getProperties();
Properties connprops = config.getProperties();
return PropertiesDecrypter.decryptAllProperties(StringEncrypter.defaultInstance(),connprops,salt);
}catch(StringEncrypter.EncryptionException e) {
throw new JansThinBridgeInitException("Failed to decrypt persistence connection parameters",e);
Expand Down
Loading

0 comments on commit 1a1de0f

Please sign in to comment.