77package org .elasticsearch .xpack .security .authc .ldap ;
88
99import org .apache .logging .log4j .LogManager ;
10+ import org .elasticsearch .ElasticsearchException ;
1011import org .elasticsearch .ElasticsearchSecurityException ;
1112import org .elasticsearch .action .ActionFuture ;
1213import org .elasticsearch .action .DocWriteResponse ;
2425import org .elasticsearch .xcontent .XContentType ;
2526import org .elasticsearch .xpack .core .security .action .rolemapping .PutRoleMappingRequestBuilder ;
2627import org .elasticsearch .xpack .core .security .action .rolemapping .PutRoleMappingResponse ;
28+ import org .elasticsearch .xpack .core .security .action .user .AuthenticateRequestBuilder ;
29+ import org .elasticsearch .xpack .core .security .action .user .AuthenticateResponse ;
2730import org .elasticsearch .xpack .core .security .authc .ldap .ActiveDirectorySessionFactorySettings ;
2831import org .elasticsearch .xpack .core .security .authc .support .UsernamePasswordToken ;
2932import org .junit .After ;
3841import java .util .List ;
3942import java .util .Map ;
4043import java .util .Objects ;
44+ import java .util .concurrent .TimeUnit ;
4145import java .util .function .Function ;
4246import java .util .function .Supplier ;
4347import java .util .stream .Collectors ;
5357import static org .elasticsearch .xpack .security .authc .ldap .AbstractActiveDirectoryTestCase .AD_LDAP_PORT ;
5458import static org .elasticsearch .xpack .security .test .SecurityTestUtils .writeFile ;
5559import static org .hamcrest .Matchers .equalTo ;
60+ import static org .hamcrest .Matchers .is ;
5661
5762/**
5863 * This test assumes all subclass tests will be of type SUITE. It picks a random realm configuration for the tests, and
@@ -246,6 +251,11 @@ protected String configRoles() {
246251
247252 protected void assertAccessAllowed (String user , String index ) throws IOException {
248253 Client client = client ().filterWithHeader (Collections .singletonMap (BASIC_AUTH_HEADER , userHeader (user , PASSWORD )));
254+
255+ // Force an authentication to populate the cache.
256+ // We can safely re-try this if it fails, which makes it less likely that the index request will fail
257+ authenticateUser (client , user , 3 );
258+
249259 IndexResponse indexResponse = client .prepareIndex (index )
250260 .setSource (jsonBuilder ().startObject ().field ("name" , "value" ).endObject ())
251261 .execute ()
@@ -265,12 +275,13 @@ protected void assertAccessAllowed(String user, String index) throws IOException
265275 }
266276
267277 protected void assertAccessDenied (String user , String index ) throws IOException {
278+ final Client client = client ().filterWithHeader (Collections .singletonMap (BASIC_AUTH_HEADER , userHeader (user , PASSWORD )));
279+ // Force an authentication to populate the cache.
280+ // We can safely re-try this if it fails, which means we can be more confident that the index request failed for the correct reason
281+ authenticateUser (client , user , 3 );
282+
268283 try {
269- client ().filterWithHeader (Collections .singletonMap (BASIC_AUTH_HEADER , userHeader (user , PASSWORD )))
270- .prepareIndex (index )
271- .setSource (jsonBuilder ().startObject ().field ("name" , "value" ).endObject ())
272- .execute ()
273- .actionGet ();
284+ client .prepareIndex (index ).setSource (jsonBuilder ().startObject ().field ("name" , "value" ).endObject ()).execute ().actionGet ();
274285 fail ("Write access to index " + index + " should not be allowed for user " + user );
275286 } catch (ElasticsearchSecurityException e ) {
276287 // expected
@@ -282,6 +293,23 @@ protected static String userHeader(String username, String password) {
282293 return UsernamePasswordToken .basicAuthHeaderValue (username , new SecureString (password .toCharArray ()));
283294 }
284295
296+ private void authenticateUser (Client client , String username , int retryCount ) {
297+ for (int i = 1 ; i <= retryCount ; i ++) {
298+ try {
299+ final AuthenticateResponse response = new AuthenticateRequestBuilder (client ).username (username )
300+ .execute ()
301+ .actionGet (10 , TimeUnit .SECONDS );
302+ assertThat (response .authentication ().getUser ().principal (), is (username ));
303+ return ;
304+ } catch (ElasticsearchException e ) {
305+ if (i == retryCount ) {
306+ throw e ;
307+ }
308+ logger .info ("Failed to authenticate [{}] - [{}], retrying" , username , e .toString ());
309+ }
310+ }
311+ }
312+
285313 /**
286314 * Collects all the certificates that are normally trusted by the node ( contained in testnode.jks )
287315 */
0 commit comments