| /* |
| * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0, which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * This Source Code may also be made available under the following Secondary |
| * Licenses when the conditions for such availability set forth in the |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, |
| * version 2 with the GNU Classpath Exception, which is available at |
| * https://www.gnu.org/software/classpath/license.html. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 |
| */ |
| |
| package test.com.sun.jaspic.config; |
| |
| import com.sun.jaspic.config.factory.AuthConfigFileFactory; |
| import com.sun.jaspic.config.servlet.JAASServletAuthConfigProvider; |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Random; |
| import java.util.StringTokenizer; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.security.auth.Subject; |
| import javax.security.auth.callback.Callback; |
| import javax.security.auth.callback.CallbackHandler; |
| import javax.security.auth.callback.UnsupportedCallbackException; |
| import jakarta.security.auth.message.AuthException; |
| import jakarta.security.auth.message.config.AuthConfigFactory; |
| import jakarta.security.auth.message.config.AuthConfigFactory.RegistrationContext; |
| import jakarta.security.auth.message.config.AuthConfigProvider; |
| import jakarta.security.auth.message.config.RegistrationListener; |
| import jakarta.security.auth.message.config.ServerAuthConfig; |
| import jakarta.security.auth.message.config.ServerAuthContext; |
| |
| /** |
| * |
| * @author Ron Monzillo |
| */ |
| public class RuntimeSurrogate { |
| |
| static final Logger logger = Logger.getLogger(RuntimeSurrogate.class.getName()); |
| private static final String CONFIG_FILE_NAME_KEY = "config.file.name"; |
| static HashMap<String, String> providerProperties = new HashMap<String, String>(); |
| AuthConfigFactory factory; |
| AuthConfigProvider provider; |
| |
| public RuntimeSurrogate(AuthConfigProvider provider, AuthConfigFactory factory) { |
| String[] regIDS = factory.getRegistrationIDs(provider); |
| for (String i : regIDS) { |
| try { |
| RegistrationContext r = factory.getRegistrationContext(i); |
| System.out.println(contextToString(r)); |
| AuthConfigProvider p = factory.getConfigProvider(r.getMessageLayer(), r.getAppContext(), null); |
| ServerAuthConfig c = p.getServerAuthConfig(r.getMessageLayer(), r.getAppContext(), |
| new CallbackHandler() { |
| |
| public void handle(Callback[] clbcks) |
| throws IOException, UnsupportedCallbackException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| }); |
| ServerAuthContext s = c.getAuthContext("0", new Subject(), new HashMap()); |
| } catch (AuthException ex) { |
| Logger.getLogger(RuntimeSurrogate.class.getName()).log(Level.SEVERE, null, ex); |
| } |
| } |
| } |
| |
| public final String contextToString(RegistrationContext r) { |
| String rvalue = r.getDescription() + "\n\t" + r.getAppContext() + "\n\t" |
| + r.getMessageLayer() + "\n\t" + r.isPersistent() + "\n"; |
| return rvalue; |
| } |
| |
| public static void main(String[] args) { |
| System.out.println("Security Manager is " |
| + (System.getSecurityManager() == null ? "OFF" : "ON")); |
| System.out.println("user.dir: " + System.getProperty("user.dir")); |
| |
| for (String s : args) { |
| StringTokenizer tokenizer = new StringTokenizer(s, "="); |
| if (tokenizer.countTokens() == 2) { |
| String key = tokenizer.nextToken(); |
| String value = tokenizer.nextToken(); |
| System.out.println("key: " + key + " value: " + value); |
| providerProperties.put(key, value); |
| } |
| } |
| |
| AuthConfigFactory.setFactory(new AuthConfigFileFactory()); |
| final AuthConfigFactory f = AuthConfigFactory.getFactory(); |
| |
| final AuthConfigProvider p = new JAASServletAuthConfigProvider(providerProperties, f); |
| RuntimeSurrogate rS = new RuntimeSurrogate(p, f); |
| /* |
| p = new SpringServletAuthConfigProvider(properties, f); |
| rS = new RuntimeSurrogate(p, f); |
| */ |
| //listenertest |
| RegistrationListener listener = |
| new RegistrationListener() { |
| |
| public void notify(String layer, String context) { |
| System.out.println("listener notified - layer: " + layer + " context: " + context); |
| f.getConfigProvider(layer, context, this); |
| } |
| }; |
| |
| String rid1 = f.registerConfigProvider(p, "x", null, "test"); |
| String rid2 = f.registerConfigProvider(p, "x", "y1", "test"); |
| |
| f.getConfigProvider("x", "y1", listener); |
| f.getConfigProvider("x", "y2", listener); |
| |
| f.removeRegistration(rid2); |
| f.removeRegistration(rid1); |
| |
| providers[0] = null; |
| for (int i = 1; i < providers.length; i++) { |
| providers[i] = new JAASServletAuthConfigProvider(providerProperties, null); |
| } |
| f.detachListener(listener, null, null); |
| testFactory(); |
| } |
| static AuthConfigProvider[] providers = new AuthConfigProvider[4]; |
| static final TestThread[] threads = new TestThread[1024]; |
| |
| public static void testFactory() { |
| |
| AuthConfigFactory.setFactory(new AuthConfigFileFactory()); |
| |
| for (int i = 0; i < threads.length; i++) { |
| threads[i] = new TestThread(); |
| } |
| for (int i = 0; i < threads.length; i++) { |
| threads[i].start(); |
| } |
| for (TestThread t : threads) { |
| try { |
| t.join(); |
| } catch (InterruptedException ex) { |
| logger.log(Level.SEVERE, "thread: " + t.getId() + " caught exception", ex); |
| } finally { |
| logger.log(Level.INFO, "thread: {0} completed: {1}", new Object[]{t.getId(), t.runAsConsumer() ? "comsumer" : "producer"}); |
| } |
| } |
| logger.info("ALL THREADS JOINED"); |
| AuthConfigFactory f = AuthConfigFactory.getFactory(); |
| String[] rids = f.getRegistrationIDs(null); |
| for (String i : rids) { |
| RegistrationContext rc = f.getRegistrationContext(i); |
| logger.log(Level.INFO, "removing registration - layer: {0} appContext: {1} description: {2} persistent: {3}", |
| new Object[]{rc.getMessageLayer(), rc.getAppContext(), |
| rc.getDescription(), rc.isPersistent()}); |
| f.removeRegistration(i); |
| } |
| logger.info("ALL REGISTRATIONS REMOVED"); |
| } |
| |
| static class TestThread extends Thread implements RegistrationListener { |
| |
| static Random random = new Random(); |
| static String[] layers = new String[4]; |
| static String[] contexts = new String[16]; |
| static int consumerCount = threads.length; |
| boolean runAsConsumer = false; |
| boolean stop; |
| |
| static { |
| layers[0] = null; |
| for (int i = 1; i < layers.length; i++) { |
| layers[i] = "layer" + Integer.toString(i); |
| } |
| contexts[0] = null; |
| for (int i = 1; i < contexts.length; i++) { |
| contexts[i] = "context" + Integer.toString(i); |
| } |
| } |
| |
| @Override |
| public void run() { |
| synchronized (TestThread.class) { |
| if (consumerCount == threads.length) { |
| runAsConsumer = false; |
| } else { |
| runAsConsumer = (random.nextInt(threads.length / 10) != 1); |
| } |
| } |
| AuthConfigFactory f = AuthConfigFactory.getFactory(); |
| if (runAsConsumer) { |
| doConsumer(f, layers[random.nextInt(layers.length)], contexts[random.nextInt(contexts.length)]); |
| } else { |
| synchronized (TestThread.class) { |
| consumerCount--; |
| logger.log(Level.INFO, "creating producer, remaining consumers: " + consumerCount); |
| } |
| while (true) { |
| synchronized (TestThread.class) { |
| if (consumerCount == 0) { |
| return; |
| } |
| } |
| switch (random.nextInt(5)) { |
| case 0: |
| if (random.nextInt(25) == 1) { |
| try { |
| f.refresh(); |
| } catch (Exception e) { |
| logger.log(Level.SEVERE, "producer thread: " + getId(), e); |
| } |
| } |
| break; |
| case 1: |
| if (random.nextInt(1000) == 1) { |
| try { |
| f = AuthConfigFactory.getFactory(); |
| AuthConfigFactory.setFactory(f); |
| } catch (Exception e) { |
| logger.log(Level.SEVERE, "producer thread: " + getId(), e); |
| } |
| } |
| break; |
| case 2: |
| try { |
| f.registerConfigProvider( |
| "servlet.JAASServletAuthConfigProvider", providerProperties, |
| layers[random.nextInt(layers.length)], |
| contexts[random.nextInt(contexts.length)], |
| "persistent registration"); |
| } catch (Exception e) { |
| logger.log(Level.SEVERE, "producer thread: " + getId(), e); |
| } |
| break; |
| case 3: |
| try { |
| f.registerConfigProvider( |
| providers[random.nextInt(providers.length)], |
| layers[random.nextInt(layers.length)], |
| contexts[random.nextInt(contexts.length)], |
| "transient registration"); |
| } catch (Exception e) { |
| logger.log(Level.SEVERE, "producer thread: " + getId(), e); |
| } |
| break; |
| case 4: |
| try { |
| String[] rids = f.getRegistrationIDs( |
| providers[random.nextInt(providers.length)]); |
| int length = rids.length; |
| boolean removeNext = true; |
| for (String rid : rids) { |
| RegistrationContext rc = f.getRegistrationContext(rid); |
| if (rc == null) { |
| removeNext = true; |
| } else if (removeNext) { |
| f.removeRegistration(rid); |
| removeNext = false; |
| } else { |
| removeNext = true; |
| } |
| } |
| } catch (Exception e) { |
| logger.log(Level.SEVERE, "producer thread: " + getId(), e); |
| } |
| break; |
| |
| } |
| } |
| } |
| } |
| |
| public boolean runAsConsumer() { |
| return runAsConsumer; |
| } |
| |
| public void doConsumer(AuthConfigFactory f, String layer, String context) { |
| |
| synchronized (TestThread.class) { |
| logger.log(Level.INFO, "creating consumer"); |
| this.stop = false; |
| } |
| try { |
| while (true) { |
| f.getConfigProvider(layer, context, this); |
| sleep(100); |
| synchronized (TestThread.class) { |
| if (this.stop) { |
| break; |
| } |
| } |
| } |
| f.detachListener(this, null, null); |
| } catch (Exception e) { |
| logger.log(Level.SEVERE, "consumer thread: " + getId(), e); |
| } finally { |
| synchronized (TestThread.class) { |
| consumerCount--; |
| logger.log(Level.INFO, "consumer thread: " + getId() + "stopping - remaining: " + consumerCount); |
| } |
| } |
| } |
| |
| public void notify(String layer, String context) { |
| if (random.nextInt(100) == 1) { |
| synchronized (TestThread.class) { |
| this.stop = true; |
| } |
| } |
| } |
| } |
| } |