diff --git a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java
index 5af2f6c8a7fe191a6d94a358a5b07fad41959399..ec211151669cb00a4854a537715a1af57b58119b 100644
--- a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java
+++ b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java
@@ -377,10 +377,13 @@ public class RestApiLoginFilter implements Filter {
 			Identity identity = securityBean.getIdentity(token);
 			int loginStatus = AuthHelper.doHeadlessLogin(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier(), ureq, true);
 			if(loginStatus == AuthHelper.LOGIN_OK) {
-				response.setHeader(RestSecurityHelper.SEC_TOKEN, securityBean.renewToken(token));
-				synchronized(uress) {
-					chain.doFilter(request, response);
-				}
+				String renewedToken = securityBean.renewToken(token);
+				if(renewedToken != null) {
+					response.setHeader(RestSecurityHelper.SEC_TOKEN, renewedToken);
+					synchronized(uress) {
+						chain.doFilter(request, response);
+					}
+				} else response.sendError(401);
 			} else response.sendError(401);
 		} else response.sendError(401);
 	}
diff --git a/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java b/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java
index 9222f9d4e02cc38def6ac235d1a9dbd855dcf2d0..1968a04649025f09258131673aecd8b1096927b1 100644
--- a/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java
+++ b/src/main/java/org/olat/restapi/security/RestSecurityBeanImpl.java
@@ -53,9 +53,9 @@ public class RestSecurityBeanImpl implements RestSecurityBean {
 	
 	public static final String REST_AUTH_PROVIDER = "REST";
 
-	private Map<String,Long> tokenToIdentity = new ConcurrentHashMap<String,Long>();
-	private Map<String,List<String>> tokenToSessionIds = new ConcurrentHashMap<String,List<String>>();
-	private Map<String,String> sessionIdToTokens = new ConcurrentHashMap<String,String>();
+	private Map<String,Long> tokenToIdentity = new ConcurrentHashMap<>();
+	private Map<String,List<String>> tokenToSessionIds = new ConcurrentHashMap<>();
+	private Map<String,String> sessionIdToTokens = new ConcurrentHashMap<>();
 	
 	@Autowired
 	private BaseSecurity securityManager;
@@ -70,7 +70,7 @@ public class RestSecurityBeanImpl implements RestSecurityBean {
 		
 		Authentication auth = securityManager.findAuthentication(identity, REST_AUTH_PROVIDER);
 		if(auth == null) {
-			auth = securityManager.createAndPersistAuthentication(identity, REST_AUTH_PROVIDER, identity.getName(), token, null);
+			securityManager.createAndPersistAuthentication(identity, REST_AUTH_PROVIDER, identity.getName(), token, null);
 		} else {
 			authenticationDao.updateCredential(auth, token);
 		}
@@ -79,6 +79,19 @@ public class RestSecurityBeanImpl implements RestSecurityBean {
 
 	@Override
 	public String renewToken(String token) {
+		if(token == null || token.length() > 40) {
+			return null;
+		}
+		// don't regex, never
+		for(char c:token.toCharArray()) {
+			if(c == '-'
+					|| (c >= 48 && c <= 57)
+					|| (c >= 65 && c <= 90)
+					|| (c >= 97 && c <= 122)) {
+				continue;
+			}
+			return null;
+		}
 		return token;
 	}
 
@@ -119,7 +132,7 @@ public class RestSecurityBeanImpl implements RestSecurityBean {
 		String sessionId = session.getId();
 		synchronized(tokenToSessionIds) {//cluster notOK -> need probably a mapping on the DB
 			if(!tokenToSessionIds.containsKey(token)) {
-				List<String> sessionIds = new ArrayList<String>();
+				List<String> sessionIds = new ArrayList<>();
 				sessionIds.add(session.getId());
 				tokenToSessionIds.put(token, sessionIds);
 			} else {
diff --git a/src/test/java/org/olat/restapi/RestConnection.java b/src/test/java/org/olat/restapi/RestConnection.java
index 0d12e054d20e3267bc546ca3abb2d85288ce1f73..493cca66255b702acda10bdf5459a1f1404084bc 100644
--- a/src/test/java/org/olat/restapi/RestConnection.java
+++ b/src/test/java/org/olat/restapi/RestConnection.java
@@ -33,7 +33,6 @@ import java.util.List;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriBuilder;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -44,6 +43,7 @@ import org.apache.http.client.CookieStore;
 import org.apache.http.client.config.CookieSpecs;
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.http.client.methods.HttpGet;
@@ -102,6 +102,17 @@ public class RestConnection {
 				.build();
 	}
 	
+	public RestConnection(boolean enableCookieStore, boolean enableCredentialProvider) {
+		HttpClientBuilder builder = HttpClientBuilder.create();
+		if(enableCookieStore) {
+			builder = builder.setDefaultCookieStore(cookieStore);
+		}
+		if(enableCredentialProvider) {
+			builder = builder.setDefaultCredentialsProvider(provider);
+		}
+		httpclient = builder.build();
+	}
+	
 	public RestConnection(URL url) {
 		PORT = url.getPort();
 		HOST = url.getHost();
@@ -151,7 +162,11 @@ public class RestConnection {
 	}
 
 	public void shutdown() {
-		IOUtils.closeQuietly(httpclient);
+		try {
+			httpclient.close();
+		} catch (IOException e) {
+			log.error("", e);
+		}
 	}
 
 	public boolean login(String username, String password) throws IOException, URISyntaxException {
@@ -161,17 +176,20 @@ public class RestConnection {
 		provider.setCredentials(new AuthScope(HOST, PORT), new UsernamePasswordCredentials(username, password));
 		provider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(username, password));
 
+		int code = -1;
 		HttpGet httpget = new HttpGet(uri);
-		HttpResponse response = httpclient.execute(httpget);
-		
-		Header header = response.getFirstHeader(RestSecurityHelper.SEC_TOKEN);
-		if(header != null) {
-			securityToken = header.getValue();
+		try(CloseableHttpResponse response = httpclient.execute(httpget)) {
+			Header header = response.getFirstHeader(RestSecurityHelper.SEC_TOKEN);
+			if(header != null) {
+				securityToken = header.getValue();
+			}
+			
+		    HttpEntity entity = response.getEntity();
+		    code = response.getStatusLine().getStatusCode();
+		    EntityUtils.consume(entity);
+		} catch(IOException e) {
+			log.error("", e);
 		}
-		
-	    HttpEntity entity = response.getEntity();
-	    int code = response.getStatusLine().getStatusCode();
-	    EntityUtils.consume(entity);
 	    return code == 200;
 	}
 	
@@ -310,8 +328,7 @@ public class RestConnection {
 	}
 	
 	public <U> U parse(HttpResponse response, Class<U> cl) {
-		try {
-			InputStream body = response.getEntity().getContent();
+		try(InputStream body = response.getEntity().getContent()) {
 			ObjectMapper mapper = new ObjectMapper(jsonFactory);
 			U obj = mapper.readValue(body, cl);
 			return obj;
diff --git a/src/test/java/org/olat/restapi/security/RestSecurityBeanTest.java b/src/test/java/org/olat/restapi/security/RestSecurityBeanTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7c7664e833c5e35cd80b11a7c29048b5cbb5d8a
--- /dev/null
+++ b/src/test/java/org/olat/restapi/security/RestSecurityBeanTest.java
@@ -0,0 +1,92 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.restapi.security;
+
+import java.util.UUID;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.olat.core.id.Identity;
+import org.olat.test.JunitTestHelper;
+import org.olat.test.OlatTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpSession;
+
+/**
+ * 
+ * Initial date: 5 mars 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class RestSecurityBeanTest extends OlatTestCase {
+	
+    @Autowired
+    private RestSecurityBean restSecurityBean;
+
+	@Test
+	public void generatedToken() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-api");
+		String token = restSecurityBean.generateToken(id, new MockHttpSession());
+		String renewedToken = restSecurityBean.renewToken(token);
+		Assert.assertEquals(token, renewedToken);
+	}
+	
+	@Test
+	public void renewToken() {
+		String token = UUID.randomUUID().toString();
+		String renewedToken = restSecurityBean.renewToken(token);
+		Assert.assertEquals(token, renewedToken);
+	}
+	
+	@Test
+	public void renewToken_09() {
+		String uuid = "0123456789";
+		String renewedToken = restSecurityBean.renewToken(uuid);
+		Assert.assertEquals(uuid, renewedToken);
+	}
+	
+	@Test
+	public void renewToken_az() {
+		String uuid = "abcdefghijklmnopqrstuvwxyz";
+		String renewedToken = restSecurityBean.renewToken(uuid);
+		Assert.assertEquals(uuid, renewedToken);
+	}
+	
+	@Test
+	public void renewToken_AZ() {
+		String uuid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+		String renewedToken = restSecurityBean.renewToken(uuid);
+		Assert.assertEquals(uuid, renewedToken);
+	}
+	
+	@Test
+	public void renewToken_tooLong() {
+		String uuid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+		String renewedToken = restSecurityBean.renewToken(uuid);
+		Assert.assertNull(renewedToken);
+	}
+	
+	@Test
+	public void renewToken_notAllowed() {
+		String uuid = "abc:test";
+		String renewedToken = restSecurityBean.renewToken(uuid);
+		Assert.assertNull(renewedToken);
+	}
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 0095f54148d9e266ce7d37c2186e4f3c3bf06aa5..4eaad3e8c391e74b37e14fab07ab2d383461a50f 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -331,6 +331,7 @@ import org.junit.runners.Suite;
 	org.olat.restapi.RegistrationTest.class,
 	org.olat.restapi.DocumentPoolModuleWebServiceTest.class,
 	org.olat.restapi.TaxonomyWebServiceTest.class,
+	org.olat.restapi.security.RestSecurityBeanTest.class,
 	de.bps.onyx.plugin.OnyxModuleTest.class,
 	de.bps.onyx.plugin.OnyxResultManagerTest.class,
 	de.bps.olat.portal.institution.InstitutionPortletTest.class,