View Javadoc
1   package edu.internet2.middleware.grouper.authentication.plugin;
2   
3   import edu.internet2.middleware.grouper.authentication.plugin.config.ClientProvider;
4   import edu.internet2.middleware.grouper.authentication.plugin.config.ClientProviders;
5   import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase;
6   import org.apache.commons.lang3.StringUtils;
7   import org.apache.commons.logging.Log;
8   import org.pac4j.core.client.Client;
9   import org.pac4j.core.client.Clients;
10  import org.pac4j.core.config.Config;
11  import org.pac4j.core.config.ConfigFactory;
12  import org.pac4j.core.matching.matcher.PathMatcher;
13  
14  import java.lang.reflect.InvocationTargetException;
15  
16  public class Pac4jConfigFactory implements ConfigFactory {
17      private static final Log LOGGER = GrouperAuthentication.getLogFactory().getInstance(Pac4jConfigFactory.class);
18  
19      @Override
20      public Config build(Object... parameters) {
21          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
22          try {
23              Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
24  
25              ConfigPropertiesCascadeBase grouperConfig = ConfigUtils.getBestGrouperConfiguration();
26  
27              String provider;
28              if (grouperConfig.containsKey("external.authentication.mechanism")) {
29                  LOGGER.warn("you're using the deprecated key `external.authentication.mechanism`; please update to `external.authentication.provider`");
30                  provider = grouperConfig.propertyValueString("external.authentication.mechanism");
31              } else {
32                  provider = grouperConfig.propertyValueString("external.authentication.provider");
33              }
34              Client client = getClient(provider);
35  
36              String callbackUrl = grouperConfig.propertyValueString("external.authentication.grouperContextUrl")
37                      + grouperConfig.propertyValueString("external.authentication.callbackUrl", "/callback");
38              final Clients clients = new Clients(callbackUrl, client);
39  
40              final Config config = new Config(clients);
41  
42              PathMatcher pathMatcher = new PathMatcher();
43  
44              String securityExclusionsPaths = grouperConfig.propertyValueString("external.authentication.exclusions", "/status");
45              if (securityExclusionsPaths != null) {
46                  for (String exclusion : securityExclusionsPaths.split(",")) {
47                      pathMatcher.excludeBranch(StringUtils.trim(exclusion));
48                  }
49              }
50              config.addMatcher("securityExclusions", pathMatcher);
51              return config;
52          } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
53              throw new RuntimeException("problem configuring pac4j", e);
54          } finally {
55              Thread.currentThread().setContextClassLoader(classLoader);
56          }
57      }
58  
59      //TODO: can this be checked
60      @SuppressWarnings("unchecked")
61      private static Client getClient(String provider) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
62          Class<? extends ClientProvider> providerClass;
63          //TODO: might be a better way of doing this
64          try {
65              providerClass = ClientProviders.fromString(provider).getProviderClass();
66          } catch (IllegalArgumentException e) {
67              try {
68                  providerClass = (Class<? extends ClientProvider>) Class.forName(provider);
69              } catch (ClassNotFoundException classNotFoundException) {
70                  throw new RuntimeException(classNotFoundException);
71              }
72          }
73          return providerClass.getDeclaredConstructor().newInstance().getClient();
74      }
75  }