diff --git a/src/main/java/org/nrg/xnat/security/XnatProviderManager.java b/src/main/java/org/nrg/xnat/security/XnatProviderManager.java index 3ca88bb0b39ac9d2a477374650ede4125e795d39..dcd35888412581ed145c64a36e82cbaaee41e377 100644 --- a/src/main/java/org/nrg/xnat/security/XnatProviderManager.java +++ b/src/main/java/org/nrg/xnat/security/XnatProviderManager.java @@ -253,9 +253,11 @@ public class XnatProviderManager extends ProviderManager { private XnatAuthenticationProvider findAuthenticationProvider(XnatAuthenticationProviderMatcher matcher) { List<AuthenticationProvider> prov = getProviders(); for (AuthenticationProvider ap : prov) { - XnatAuthenticationProvider xap = (XnatAuthenticationProvider) ap; - if (matcher.matches(xap)) { - return xap; + if(XnatAuthenticationProvider.class.isAssignableFrom(ap.getClass())) { + XnatAuthenticationProvider xap = (XnatAuthenticationProvider) ap; + if (matcher.matches(xap)) { + return xap; + } } } return null; diff --git a/src/main/java/org/nrg/xnat/security/alias/AliasTokenAuthenticationProvider.java b/src/main/java/org/nrg/xnat/security/alias/AliasTokenAuthenticationProvider.java index e0de6d27d59cc18d65af8055b4225d9fdcb010d8..51840c2d3f878a0ce23cd1646345e005be9a607e 100644 --- a/src/main/java/org/nrg/xnat/security/alias/AliasTokenAuthenticationProvider.java +++ b/src/main/java/org/nrg/xnat/security/alias/AliasTokenAuthenticationProvider.java @@ -110,6 +110,16 @@ public class AliasTokenAuthenticationProvider extends AbstractUserDetailsAuthent return getName(); } + @Override + public int getOrder() { + return _order; + } + + @Override + public void setOrder(int order) { + _order = order; + } + @Override protected void additionalAuthenticationChecks(final UserDetails userDetails, final UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { if (authentication.getCredentials() == null) { @@ -173,4 +183,5 @@ public class AliasTokenAuthenticationProvider extends AbstractUserDetailsAuthent private final AliasTokenService _aliasTokenService; private final XdatUserAuthService _userAuthService; + private int _order = -1; } diff --git a/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java b/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java index 6990368e825463d43f11210b3534c5b69b015cc4..f7ac4ba691be2aaf1910adcbd42410287533d5ed 100644 --- a/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java +++ b/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java @@ -2,6 +2,7 @@ package org.nrg.xnat.security.config; import org.apache.commons.lang3.StringUtils; import org.nrg.framework.utilities.BasicXnatResourceLocator; +import org.nrg.xnat.security.provider.XnatAuthenticationProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; @@ -13,29 +14,33 @@ import java.util.*; public class AuthenticationProviderAggregator extends ArrayList<AuthenticationProvider> { public AuthenticationProviderAggregator(List<AuthenticationProvider> standaloneProviders, Map<String, AuthenticationProviderConfigurator> configurators) { - ArrayList<String> providerArray = new ArrayList<>(); - String dbName = "Database"; - String dbId = "localdb"; - String dbType = "db"; - providerArray.add(dbType); - HashMap<String, HashMap<String, String>> providerMap = new HashMap<>(); - providerMap.put(dbType, new HashMap<String, String>()); - providerMap.get(dbType).put("name", dbName); - providerMap.get(dbType).put("id", dbId); - providerMap.get(dbType).put("type", dbType); + ArrayList<HashMap<String, String>> providerList = new ArrayList<>(); // Populate map of properties try { String filenameEnd = "-provider.properties"; final List<Resource> resources = BasicXnatResourceLocator.getResources("classpath*:META-INF/xnat/auth/**/*" + filenameEnd); - for (final Resource resource : resources) { - String filename = resource.getFilename(); - String id = filename.substring(0, (filename.length() - filenameEnd.length())); - providerMap.put(id, new HashMap<String, String>()); - providerArray.add(id); - final Properties provider = PropertiesLoaderUtils.loadProperties(resource); - for (Map.Entry<Object, Object> providerProperty : provider.entrySet()) { - providerMap.get(id).put(providerProperty.getKey().toString(), providerProperty.getValue().toString()); + if(resources==null || resources.isEmpty()){ + String dbName = "Database"; + String dbId = "localdb"; + String dbType = "db"; + HashMap<String, String> dbProv = new HashMap<String, String>(); + dbProv.put("name", dbName); + dbProv.put("id", dbId); + dbProv.put("type", dbType); + providerList.add(dbProv); + } + else { + for (final Resource resource : resources) { + String filename = resource.getFilename(); + String id = filename.substring(0, (filename.length() - filenameEnd.length())); + HashMap<String, String> newProv = new HashMap<String, String>(); + + final Properties provider = PropertiesLoaderUtils.loadProperties(resource); + for (Map.Entry<Object, Object> providerProperty : provider.entrySet()) { + newProv.put(providerProperty.getKey().toString(), providerProperty.getValue().toString()); + } + providerList.add(newProv); } } } catch (Exception e) { @@ -43,10 +48,10 @@ public class AuthenticationProviderAggregator extends ArrayList<AuthenticationPr } // Create providers - for (String prov : providerArray) { - String name = providerMap.get(prov).get("name"); - String id = providerMap.get(prov).get("id"); - String type = providerMap.get(prov).get("type"); + for (HashMap<String, String> prov : providerList) { + String name = prov.get("name"); + String id = prov.get("id"); + String type = prov.get("type"); assert !StringUtils.isBlank(name) : "You must provide a name for all authentication provider configurations"; assert !StringUtils.isBlank(id) : "You must provide an ID for all authentication provider configurations"; @@ -54,13 +59,37 @@ public class AuthenticationProviderAggregator extends ArrayList<AuthenticationPr if (configurators.containsKey(type)) { AuthenticationProviderConfigurator configurator = configurators.get(type); - addAll(configurator.getAuthenticationProviders(id, name, providerMap.get(prov))); + + addAll(configurator.getAuthenticationProviders(id, name, prov)); } } if (standaloneProviders != null) { addAll(standaloneProviders); } + + Collections.sort(this, new Comparator<AuthenticationProvider>(){ + public int compare(AuthenticationProvider o1, AuthenticationProvider o2){ + if(XnatAuthenticationProvider.class.isAssignableFrom(o1.getClass())){ + if(XnatAuthenticationProvider.class.isAssignableFrom(o2.getClass())){ + if(((XnatAuthenticationProvider)o1).getOrder() == ((XnatAuthenticationProvider)o2).getOrder()) + return 0; + return ((XnatAuthenticationProvider)o1).getOrder() < ((XnatAuthenticationProvider)o2).getOrder() ? -1 : 1; + } + else{ + return 1; + } + } + else{ + if(XnatAuthenticationProvider.class.isAssignableFrom(o2.getClass())){ + return -1; + } + else{ + return 0; + } + } + } + }); } private static final Logger _log = LoggerFactory.getLogger(AuthenticationProviderAggregator.class); diff --git a/src/main/java/org/nrg/xnat/security/config/DatabaseAuthenticationProviderConfigurator.java b/src/main/java/org/nrg/xnat/security/config/DatabaseAuthenticationProviderConfigurator.java index 0b306e52346e53bdbcb28f175182e02eb2c3e3f4..f9fba0b3c81bf01c0ea61873ed38cfa2f8252486 100644 --- a/src/main/java/org/nrg/xnat/security/config/DatabaseAuthenticationProviderConfigurator.java +++ b/src/main/java/org/nrg/xnat/security/config/DatabaseAuthenticationProviderConfigurator.java @@ -11,6 +11,7 @@ package org.nrg.xnat.security.config; import org.nrg.xdat.preferences.SiteConfigPreferences; +import org.nrg.xnat.security.provider.XnatAuthenticationProvider; import org.nrg.xnat.security.provider.XnatDatabaseAuthenticationProvider; import org.nrg.xnat.security.userdetailsservices.XnatDatabaseUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; @@ -51,7 +52,15 @@ public class DatabaseAuthenticationProviderConfigurator extends AbstractAuthenti @Override public List<AuthenticationProvider> getAuthenticationProviders(String id, String name, Map<String, String> properties) { - return getAuthenticationProviders(id, name); + List<AuthenticationProvider> provs = getAuthenticationProviders(id, name); + for(AuthenticationProvider prov : provs){ + if(XnatAuthenticationProvider.class.isAssignableFrom(prov.getClass())){ + if (properties.get("order") != null) { + ((XnatAuthenticationProvider)prov).setOrder(Integer.parseInt(properties.get("order"))); + } + } + } + return provs; } private final XnatDatabaseUserDetailsService _userDetailsService; diff --git a/src/main/java/org/nrg/xnat/security/config/LdapAuthenticationProviderConfigurator.java b/src/main/java/org/nrg/xnat/security/config/LdapAuthenticationProviderConfigurator.java index 851f87ef2c27d02f505e9676212dc24bce2586a5..1956761fe2fc80521c3d3f61ef62e9440748be64 100644 --- a/src/main/java/org/nrg/xnat/security/config/LdapAuthenticationProviderConfigurator.java +++ b/src/main/java/org/nrg/xnat/security/config/LdapAuthenticationProviderConfigurator.java @@ -49,6 +49,9 @@ public class LdapAuthenticationProviderConfigurator extends AbstractAuthenticati ldapAuthProvider.setUserDetailsContextMapper(new XnatLdapUserDetailsMapper(id, properties, _userAuthService, _preferences)); ldapAuthProvider.setName(name); ldapAuthProvider.setProviderId(id); + if (properties.get("order") != null) { + ldapAuthProvider.setOrder(Integer.parseInt(properties.get("order"))); + } return Arrays.asList(new AuthenticationProvider[] { ldapAuthProvider }); } catch (Exception exception) { _log.error("Something went wrong when configuring the LDAP authentication provider", exception); diff --git a/src/main/java/org/nrg/xnat/security/provider/XnatAuthenticationProvider.java b/src/main/java/org/nrg/xnat/security/provider/XnatAuthenticationProvider.java index 76535627b587c9ba154ae4e1a71195b4fb29cfca..a23011a59a71fa9978e434825d43f9ccb7fd0926 100644 --- a/src/main/java/org/nrg/xnat/security/provider/XnatAuthenticationProvider.java +++ b/src/main/java/org/nrg/xnat/security/provider/XnatAuthenticationProvider.java @@ -40,4 +40,13 @@ public interface XnatAuthenticationProvider extends AuthenticationProvider { * @return The authentication method for this provider. */ String getAuthMethod(); + + /** + * Indicates the order associated with this provider. This is used to determine the order in which the providers + * show up in the login dropdown and the order in which they are checked when a login is attempted. + * @return The order for this provider. + */ + int getOrder(); + + void setOrder(int order); } diff --git a/src/main/java/org/nrg/xnat/security/provider/XnatDatabaseAuthenticationProvider.java b/src/main/java/org/nrg/xnat/security/provider/XnatDatabaseAuthenticationProvider.java index 8dac7b2415dfef434d0a4e7f8abfd0775222f286..3ad7b36ade6addefcff69153cba94673119ed416 100644 --- a/src/main/java/org/nrg/xnat/security/provider/XnatDatabaseAuthenticationProvider.java +++ b/src/main/java/org/nrg/xnat/security/provider/XnatDatabaseAuthenticationProvider.java @@ -74,6 +74,16 @@ public class XnatDatabaseAuthenticationProvider extends DaoAuthenticationProvide return XdatUserAuthService.LOCALDB; } + @Override + public int getOrder() { + return _order; + } + + @Override + public void setOrder(int order) { + _order = order; + } + @Override protected void additionalAuthenticationChecks(final UserDetails userDetails, final UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { if (!UserI.class.isAssignableFrom(userDetails.getClass())) { @@ -143,4 +153,5 @@ public class XnatDatabaseAuthenticationProvider extends DaoAuthenticationProvide } private final boolean _requireEmailVerification; + private int _order = -1; } diff --git a/src/main/java/org/nrg/xnat/security/provider/XnatLdapAuthenticationProvider.java b/src/main/java/org/nrg/xnat/security/provider/XnatLdapAuthenticationProvider.java index c57c49edcf03ece272e78e0696c10e7594423d5a..20fa4dc3bd826bf590ac2da0f4051f7253b015a5 100644 --- a/src/main/java/org/nrg/xnat/security/provider/XnatLdapAuthenticationProvider.java +++ b/src/main/java/org/nrg/xnat/security/provider/XnatLdapAuthenticationProvider.java @@ -94,6 +94,16 @@ public class XnatLdapAuthenticationProvider extends LdapAuthenticationProvider i return XdatUserAuthService.LDAP; } + @Override + public int getOrder() { + return _order; + } + + @Override + public void setOrder(int order) { + _order = order; + } + /** * Indicates whether the provider should be visible to and selectable by users. <b>false</b> usually indicates an * internal authentication provider, e.g. token authentication. @@ -109,4 +119,5 @@ public class XnatLdapAuthenticationProvider extends LdapAuthenticationProvider i private String _displayName = ""; private String _providerId = ""; + private int _order = -1; }