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
60 @SuppressWarnings("unchecked")
61 private static Client getClient(String provider) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
62 Class<? extends ClientProvider> providerClass;
63
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 }