diff --git a/conf/core/server.conf b/conf/core/server.conf index 66d59c276eba895c7f7885292dc004634c7d20f3..e8281657dd1c9a7aa92bd94c7c974e93b0fee5c4 100644 --- a/conf/core/server.conf +++ b/conf/core/server.conf @@ -114,10 +114,17 @@ CERTIFICATES_KEY_STORE_PASSWORD= # 10 min SESSION_TIMEOUT_MS=600000 -# Time after which activation tokens for the activation of new users (internal -# user sources) expire. +# Time after which one-time tokens expire. +# This is only a default value. The actual timeout of each token can be +# configured otherwise. # 7days -ACTIVATION_TIMEOUT_MS=604800000 +ONE_TIME_TOKEN_EXPIRES_MS=604800000 + +# Timeout after which a consumed one-time token expires regardless of the +# maximum of attempts that are allowed for that token. This is only a default +# value. The actual timeout of each token can be configured otherwise. +# 30 s +ONE_TIME_TOKEN_ATTEMPTS_TIMEOUT_MS=30000 # The value for the HTTP cache directive "max-age" WEBUI_HTTP_HEADER_CACHE_MAX_AGE=28800 diff --git a/src/main/java/caosdb/server/CaosDBServer.java b/src/main/java/caosdb/server/CaosDBServer.java index eb4f7df164b7362641d0c963332b4905291f2642..4b0ead406d99ceb4214eed55c08caf8aea5e19f4 100644 --- a/src/main/java/caosdb/server/CaosDBServer.java +++ b/src/main/java/caosdb/server/CaosDBServer.java @@ -311,6 +311,11 @@ public class CaosDBServer extends Application { } } + public static void initOneTimeTokens() throws Exception { + OneTimeAuthenticationToken.initConfig(); + OneTimeAuthenticationToken.initConsumedInfoCleanup(); + } + /** * This main method starts up a web application that will listen on a port defined in the config * file. @@ -330,7 +335,7 @@ public class CaosDBServer extends Application { initScheduler(); initServerProperties(); initTimeZone(); - OneTimeAuthenticationToken.init(); + initOneTimeTokens(); initShiro(); initBackend(); initWebServer(); diff --git a/src/main/java/caosdb/server/ServerProperties.java b/src/main/java/caosdb/server/ServerProperties.java index 292d99e7ff6eedf39d0aee71b5f2df0f879b6a64..08ffc43488e2f49e6d44c34ab0e0927b8ee2a5db 100644 --- a/src/main/java/caosdb/server/ServerProperties.java +++ b/src/main/java/caosdb/server/ServerProperties.java @@ -88,7 +88,9 @@ public class ServerProperties extends Properties { public static final String KEY_BUGTRACKER_URI = "BUGTRACKER_URI"; public static final String KEY_SESSION_TIMEOUT_MS = "SESSION_TIMEOUT_MS"; - public static final String KEY_ACTIVATION_TIMEOUT_MS = "ACTIVATION_TIMEOUT_MS"; + public static final String KEY_ONE_TIME_TOKEN_EXPIRES_MS = "ONE_TIME_TOKEN_EXPIRES_MS"; + public static final String KEY_ONE_TIME_TOKEN_ATTEMPTS_TIMEOUT_MS = + "ONE_TIME_TOKEN_ATTEMPTS_TIMEOUT_MS"; public static final String KEY_CACHE_CONF_LOC = "CACHE_CONF_LOC"; public static final String KEY_CACHE_DISABLE = "CACHE_DISABLE"; diff --git a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java index 72edefb303b4391321f30b807e951fd407962a43..16b48b54dbca9ab0bf51b4001dcee7ddeac42c41 100644 --- a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java +++ b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java @@ -51,6 +51,14 @@ import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerBuilder; +class ConsumedInfoCleanupJob implements Job { + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + OneTimeAuthenticationToken.cleanupConsumedInfo(); + } +} + class ConsumedInfo { private OneTimeAuthenticationToken oneTimeAuthenticationToken; @@ -60,34 +68,55 @@ class ConsumedInfo { this.oneTimeAuthenticationToken = oneTimeAuthenticationToken; } - public String getKey() { - return getKey(oneTimeAuthenticationToken); - } - public static String getKey(OneTimeAuthenticationToken token) { return token.checksum; } - public int getNoOfAttempts() { + private int getNoOfAttempts() { return attempts.size(); } - public long getMaxAttempts() { + private long getMaxAttempts() { return oneTimeAuthenticationToken.getMaxAttempts(); } + private long getAttemptTimeout() { + if (attempts.size() == 0) { + return Long.MAX_VALUE; + } + long firstAttemptTime = attempts.get(0); + return firstAttemptTime + oneTimeAuthenticationToken.getAttemptsTimeout(); + } + public void consume() { - if (getNoOfAttempts() >= getMaxAttempts()) { - throw new AuthenticationException("One-token was consumed too often."); + synchronized (attempts) { + if (getNoOfAttempts() >= getMaxAttempts()) { + throw new AuthenticationException("One-time token was consumed too often."); + } else if (getAttemptTimeout() < System.currentTimeMillis()) { + throw new AuthenticationException("One-time token attempts timeout expired."); + } + attempts.add(System.currentTimeMillis()); } - attempts.add(System.currentTimeMillis()); + } + + public boolean isExpired() { + return oneTimeAuthenticationToken.isExpired(); } } public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToken { + public static final long DEFAULT_MAX_ATTEMPTS = 1L; + public static final int DEFAULT_ATTEMPTS_TIMEOUT_MS = + Integer.parseInt( + CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_ATTEMPTS_TIMEOUT_MS)); + public static final int DEFAULT_TIMEOUT_MS = + Integer.parseInt( + CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_EXPIRES_MS)); + private static Map<String, ConsumedInfo> consumedOneTimeTokens = new HashMap<>(); private long maxAttempts; + private long attemptsTimeout; public OneTimeAuthenticationToken( final Principal principal, @@ -98,12 +127,32 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final String checksum, final String[] permissions, final String[] roles, - final long maxAttempts) { + final long maxAttempts, + final long attemptsTimeout) { super(principal, date, timeout, salt, curry, checksum, permissions, roles); + this.attemptsTimeout = attemptsTimeout; this.maxAttempts = maxAttempts; consume(); } + /** TODO not yet called anywhere */ + public static void cleanupConsumedInfo() { + synchronized (consumedOneTimeTokens) { + for (Iterator<Map.Entry<String, ConsumedInfo>> it = + consumedOneTimeTokens.entrySet().iterator(); + it.hasNext(); ) { + Map.Entry<String, ConsumedInfo> next = it.next(); + if (next.getValue().isExpired()) { + it.remove(); + } + } + } + } + + public long getAttemptsTimeout() { + return attemptsTimeout; + } + public void consume() { consume(this); } @@ -111,10 +160,13 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke public static void consume(OneTimeAuthenticationToken oneTimeAuthenticationToken) { if (oneTimeAuthenticationToken.isValid()) { String key = ConsumedInfo.getKey(oneTimeAuthenticationToken); - ConsumedInfo consumedInfo = consumedOneTimeTokens.get(key); - if (consumedInfo == null) { - consumedInfo = new ConsumedInfo(oneTimeAuthenticationToken); - consumedOneTimeTokens.put(key, consumedInfo); + ConsumedInfo consumedInfo = null; + synchronized (consumedOneTimeTokens) { + consumedInfo = consumedOneTimeTokens.get(key); + if (consumedInfo == null) { + consumedInfo = new ConsumedInfo(oneTimeAuthenticationToken); + consumedOneTimeTokens.put(key, consumedInfo); + } } consumedInfo.consume(); } else { @@ -128,8 +180,16 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final String curry, final String[] permissions, final String[] roles, - final Long maxAttempts) { - super(principal, timeout, curry, permissions, roles, maxAttempts != null ? maxAttempts : 1); + final Long maxAttempts, + final Long attemptsTimeout) { + super( + principal, + timeout, + curry, + permissions, + roles, + defaultIfNull(maxAttempts, DEFAULT_MAX_ATTEMPTS), + defaultIfNull(attemptsTimeout, DEFAULT_ATTEMPTS_TIMEOUT_MS)); } private static final long serialVersionUID = -1072740888045267613L; @@ -150,8 +210,18 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final String salt = (String) array[7]; final String checksum = (String) array[8]; final long maxAttempts = (Long) array[9]; + final long attemptsTimeout = (Long) array[10]; return new OneTimeAuthenticationToken( - principal, date, timeout, salt, curry, checksum, permissions, roles, maxAttempts); + principal, + date, + timeout, + salt, + curry, + checksum, + permissions, + roles, + maxAttempts, + attemptsTimeout); } private static OneTimeAuthenticationToken generate( @@ -160,10 +230,11 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final String[] permissions, final String[] roles, final long timeout, - final long maxAttempts) { + final long maxAttempts, + final long attemptsTimeout) { return new OneTimeAuthenticationToken( - principal, timeout, curry, permissions, roles, maxAttempts); + principal, timeout, curry, permissions, roles, maxAttempts, attemptsTimeout); } public static List<Config> loadConfig(InputStream input) throws Exception { @@ -205,10 +276,16 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke public static OneTimeAuthenticationToken generate(Config c, Principal principal, String curry) { return generate( - principal, curry, c.getPermissions(), c.getRoles(), c.getTimeout(), c.getMaxAttempts()); + principal, + curry, + c.getPermissions(), + c.getRoles(), + c.getTimeout(), + c.getMaxAttempts(), + c.getAttemptsTimeout()); } - static Map<String, Config> purposes; + static Map<String, Config> purposes = new HashMap<>(); public static class Output implements Job { private String file = null; @@ -276,9 +353,8 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke private String purpose = null; private Output output = null; private int maxAttempts = 1; - private int timeout = - Integer.parseInt( - CaosDBServer.getServerProperty(ServerProperties.KEY_ACTIVATION_TIMEOUT_MS)); + private int timeout = DEFAULT_TIMEOUT_MS; + private int attemptsTimeout = DEFAULT_ATTEMPTS_TIMEOUT_MS; public Config() {} @@ -290,6 +366,10 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke this.timeout = timeout; } + public void setAttemptsTimeoutSeconds(int seconds) { + this.setAttemptsTimeout(seconds * 1000); + } + public void setExpiresAfterSeconds(int seconds) { this.setTimeout(seconds * 1000); } @@ -333,16 +413,24 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke public void setOutput(Output output) { this.output = output; } + + public int getAttemptsTimeout() { + return attemptsTimeout; + } + + public void setAttemptsTimeout(int attemptsTimeout) { + this.attemptsTimeout = attemptsTimeout; + } } public static Map<String, Config> getPurposeMap() { return purposes; } - public static void init(InputStream yamlConfig) throws Exception { + public static void initConfig(InputStream yamlConfig) throws Exception { List<Config> configs = loadConfig(yamlConfig); initOutput(configs); - purposes = getPurposeMap(configs); + purposes.putAll(getPurposeMap(configs)); } private static void initOutput(List<Config> configs) throws IOException, SchedulerException { @@ -353,18 +441,32 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke } } - public static void init() throws Exception { + public static void initConfig() throws Exception { + resetConfig(); try (FileInputStream f = new FileInputStream("conf/ext/authtoken.yaml")) { - init(f); + initConfig(f); } catch (FileNotFoundException e) { // TODO log and use default config + e.printStackTrace(); } } + public static void initConsumedInfoCleanup() throws SchedulerException { + JobDetail job = JobBuilder.newJob(ConsumedInfoCleanupJob.class).build(); + Trigger trigger = + TriggerBuilder.newTrigger() + .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(0, 0)) + .build(); + CaosDBServer.scheduleJob(job, trigger); + } + @Override protected void setFields(Object[] fields) { - if (fields.length == 1) { + if (fields.length == 2) { this.maxAttempts = (long) fields[0]; + this.attemptsTimeout = (long) fields[1]; + } else { + throw new InstantiationError("Too few arguments."); } } @@ -397,11 +499,16 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke this.timeout, this.salt, this.checksum, - this.maxAttempts + this.maxAttempts, + this.attemptsTimeout }); } public long getMaxAttempts() { return maxAttempts; } + + public static void resetConfig() { + purposes.clear(); + } } diff --git a/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java index 31192c66d38027a870142b32d58e52800af1fb31..5de7cb21c52bb498eb0b065f607f3de0110741bc 100644 --- a/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java +++ b/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java @@ -53,6 +53,13 @@ public abstract class SelfValidatingAuthenticationToken extends Principal return Utils.getUID(); } + protected static <T> T defaultIfNull(T val, T def) { + if (val != null) { + return val; + } + return def; + } + public SelfValidatingAuthenticationToken( final Principal principal, final long date, @@ -74,17 +81,18 @@ public abstract class SelfValidatingAuthenticationToken extends Principal final String[] permissions, final String[] roles, String checksum, - boolean calcChecksum, + boolean newChecksum, Object... fields) { super(principal); this.date = date; this.timeout = timeout; this.salt = salt; this.curry = curry; - this.permissions = permissions != null ? permissions : new String[] {}; - this.roles = roles != null ? roles : new String[] {}; - setFields(fields); - this.checksum = checksum == null && calcChecksum ? calcChecksum() : checksum; + this.permissions = defaultIfNull(permissions, new String[] {}); + this.roles = defaultIfNull(roles, new String[] {}); + if (fields.length > 0) setFields(fields); + // only calculate a checksum iff none is given and newChecksum is explicitly 'true'. + this.checksum = checksum == null && newChecksum ? calcChecksum() : checksum; } protected abstract void setFields(Object[] fields); diff --git a/src/main/java/caosdb/server/accessControl/UserSources.java b/src/main/java/caosdb/server/accessControl/UserSources.java index be7cd286965963b7fef6372c004d3c5142f77ea9..b4c0951e7f741e393bfc8f6bdfa0ec4ca92030e2 100644 --- a/src/main/java/caosdb/server/accessControl/UserSources.java +++ b/src/main/java/caosdb/server/accessControl/UserSources.java @@ -25,6 +25,7 @@ package caosdb.server.accessControl; import caosdb.server.CaosDBServer; import caosdb.server.ServerProperties; import caosdb.server.entity.Message; +import caosdb.server.permissions.Role; import caosdb.server.transaction.RetrieveRoleTransaction; import caosdb.server.transaction.RetrieveUserTransaction; import caosdb.server.utils.ServerMessages; @@ -67,10 +68,9 @@ import org.slf4j.LoggerFactory; */ public class UserSources extends HashMap<String, UserSource> { - public static final String ANONYMOUS_ROLE = "anonymous"; private static final Logger logger = LoggerFactory.getLogger(UserSources.class); public static final String KEY_DEFAULT_REALM = "defaultRealm"; - public static final String KEY_REALMS = "defaultRealm"; + public static final String KEY_REALMS = "realms"; public static final String KEY_REALM_CLASS = "class"; private static final long serialVersionUID = 6782744064206400521L; @@ -130,14 +130,11 @@ public class UserSources extends HashMap<String, UserSource> { private Ini map = null; public void initMap() { - this.map = null; - try { - final FileInputStream f = - new FileInputStream( - CaosDBServer.getServerProperty(ServerProperties.KEY_USER_SOURCES_INI_FILE)); - this.map = new Ini(); + this.map = new Ini(); + try (final FileInputStream f = + new FileInputStream( + CaosDBServer.getServerProperty(ServerProperties.KEY_USER_SOURCES_INI_FILE))) { this.map.load(f); - f.close(); } catch (final FileNotFoundException e) { e.printStackTrace(); } catch (final IOException e) { @@ -199,7 +196,7 @@ public class UserSources extends HashMap<String, UserSource> { if (AnonymousAuthenticationToken.PRINCIPAL == principal) { // anymous has one role Set<String> roles = new HashSet<>(); - roles.add(ANONYMOUS_ROLE); + roles.add(Role.ANONYMOUS_ROLE.toString()); return roles; } diff --git a/src/main/java/caosdb/server/permissions/Role.java b/src/main/java/caosdb/server/permissions/Role.java index 70e1a61f754b4beeffe8f8fe203b42842d49cb6d..87b5d2474c4d2d3f13fd2787aaf5b11a1245a39c 100644 --- a/src/main/java/caosdb/server/permissions/Role.java +++ b/src/main/java/caosdb/server/permissions/Role.java @@ -22,7 +22,6 @@ */ package caosdb.server.permissions; -import caosdb.server.accessControl.UserSources; import java.util.HashMap; import org.jdom2.Attribute; import org.jdom2.Element; @@ -31,7 +30,7 @@ public class Role implements ResponsibleAgent { public static final Role OWNER_ROLE = new Role("?OWNER?"); public static final Role OTHER_ROLE = new Role("?OTHER?"); - public static final Role ANONYMOUS_ROLE = new Role(UserSources.ANONYMOUS_ROLE); + public static final Role ANONYMOUS_ROLE = new Role("anonymous"); private final String role; diff --git a/src/main/java/caosdb/server/resource/ScriptingResource.java b/src/main/java/caosdb/server/resource/ScriptingResource.java index 68e2203e9e24a8332a3629db82dce09a0abc552e..715892b0e76c124947ea917d8625b5d2256a2caa 100644 --- a/src/main/java/caosdb/server/resource/ScriptingResource.java +++ b/src/main/java/caosdb/server/resource/ScriptingResource.java @@ -25,9 +25,9 @@ package caosdb.server.resource; import caosdb.server.FileSystem; +import caosdb.server.accessControl.AuthenticationUtils; import caosdb.server.accessControl.OneTimeAuthenticationToken; import caosdb.server.accessControl.SessionToken; -import caosdb.server.accessControl.UserSources; import caosdb.server.entity.FileProperties; import caosdb.server.entity.Message; import caosdb.server.scripting.CallerSerializer; @@ -205,7 +205,7 @@ public class ScriptingResource extends AbstractCaosDBServerResource { } public boolean isAnonymous() { - return getUser().hasRole(UserSources.ANONYMOUS_ROLE); + return AuthenticationUtils.isAnonymous(getUser()); } public Object generateAuthToken(String call) { diff --git a/src/test/java/caosdb/server/authentication/AuthTokenTest.java b/src/test/java/caosdb/server/authentication/AuthTokenTest.java index 0f5e2e4837a96887871d6ac15c5c971fa7b50b81..504c402983c967366a0ec2ff28efc46f2c1f91df 100644 --- a/src/test/java/caosdb/server/authentication/AuthTokenTest.java +++ b/src/test/java/caosdb/server/authentication/AuthTokenTest.java @@ -55,6 +55,7 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.subject.Subject; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -77,6 +78,11 @@ public class AuthTokenTest { CaosDBServer.initShiro(); } + @Before + public void reset() { + OneTimeAuthenticationToken.resetConfig(); + } + @Test public void testSessionToken() throws InterruptedException { final String curry = "somecurry"; @@ -223,7 +229,8 @@ public class AuthTokenTest { curry, new String[] {"permissions"}, new String[] {"roles"}, - 1L); + 1L, + 3000L); Assert.assertEquals(1L, t1.getMaxAttempts()); Assert.assertFalse(t1.isExpired()); Assert.assertTrue(t1.isHashValid()); @@ -251,7 +258,8 @@ public class AuthTokenTest { curry, new String[] {"permissions"}, new String[] {"roles"}, - 3L); + 3L, + 3000L); Assert.assertFalse(t1.isExpired()); Assert.assertTrue(t1.isHashValid()); Assert.assertTrue(t1.isValid()); @@ -278,7 +286,8 @@ public class AuthTokenTest { curry, new String[] {"permissions"}, new String[] {"roles"}, - 3L); + 3L, + 3000L); Assert.assertFalse(t1.isExpired()); Assert.assertTrue(t1.isHashValid()); Assert.assertTrue(t1.isValid()); @@ -329,7 +338,7 @@ public class AuthTokenTest { Assert.assertEquals( Integer.parseInt( - CaosDBServer.getServerProperty(ServerProperties.KEY_ACTIVATION_TIMEOUT_MS)), + CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_EXPIRES_MS)), config.getTimeout()); Assert.assertEquals(1, config.getMaxAttempts()); Assert.assertNull("no purpose", config.getPurpose()); @@ -352,7 +361,7 @@ public class AuthTokenTest { testYaml.append(" - \"permission3\"\n"); testYaml.append(" - \"permission with white space\"\n"); - OneTimeAuthenticationToken.init(new CharSequenceInputStream(testYaml, "utf-8")); + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); Assert.assertNotNull("test purpose there", map.get("test purpose 1")); Assert.assertTrue("parsing to Config object", map.get("test purpose 1") instanceof Config); @@ -377,7 +386,7 @@ public class AuthTokenTest { testYaml.append(" - \"permission3\"\n"); testYaml.append(" - \"permission with white space\"\n"); - OneTimeAuthenticationToken.init(new CharSequenceInputStream(testYaml, "utf-8")); + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); Config config = map.get("no roles test"); @@ -393,7 +402,7 @@ public class AuthTokenTest { testYaml.append(" - \"permission3\"\n"); testYaml.append(" - \"permission with white space\"\n"); - OneTimeAuthenticationToken.init(new CharSequenceInputStream(testYaml, "utf-8")); + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); Assert.assertEquals(map.size(), 0); } @@ -406,7 +415,7 @@ public class AuthTokenTest { testYaml.append("- purpose: purpose 3\n"); testYaml.append("- purpose: purpose 4\n"); - OneTimeAuthenticationToken.init(new CharSequenceInputStream(testYaml, "utf-8")); + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); Assert.assertEquals("four items", 4, map.size()); Assert.assertTrue(map.get("purpose 2") instanceof Config); @@ -423,7 +432,7 @@ public class AuthTokenTest { testYaml.append(" permissions: [ permission1 ]\n"); // write the token - OneTimeAuthenticationToken.init(new CharSequenceInputStream(testYaml, "utf-8")); + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); Assert.assertTrue(tempFile.exists()); try (BufferedReader reader = new BufferedReader(new FileReader(tempFile))) { OneTimeAuthenticationToken token = @@ -446,7 +455,7 @@ public class AuthTokenTest { testYaml.append("permissions:\n"); testYaml.append(" - permission1\n"); - OneTimeAuthenticationToken.init(new CharSequenceInputStream(testYaml, "utf-8")); + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); Subject anonymous = SecurityUtils.getSubject(); anonymous.login(AnonymousAuthenticationToken.getInstance());