private Optional<HttpServletRequest> tryToGetAuthenticatedRequest(final HttpServletRequest request, final Credentials credentials) { try (final LDAPConnection ldap = ldapConnectionFactory.buildLdapConnection()) { for (String baseDN : ldapProperties.getBaseDn()) { final String userDN = userDnFrom(credentials, baseDN); try { if (authenticate(ldap, userDN, credentials.getPassword())) { return ldapProperties.getRoleBaseDn() != null ? Optional.of(new LdapRoleCheckingRequest(request, ldap, userDN, ldapProperties)) : Optional.of(request); } } catch (LDAPBindException e) { LOG.debug("LDAPBindException for userDN: {}", userDN); } } LOG.warn("Could not bind to LDAP: {}", credentials.getUsername()); } catch (LDAPException | GeneralSecurityException e) { LOG.warn("Authentication error: ", e); } return Optional.empty(); }
@Test public void shouldApplyFilterToAuthenticatedUser() throws IOException, ServletException, GeneralSecurityException, LDAPException { final LdapProperties ldapProperties = ldapProperties("someHost", 389, singletonList("someBaseDn"), null, "someRdnIdentifier", singletonList("/internal"), StartTLS, WHITELISTED_PATH); final LdapConnectionFactory connectionFactory = mock(LdapConnectionFactory.class); final LDAPConnection ldapConnection = someLdapConnectionReturning(SUCCESS); when(connectionFactory.buildLdapConnection()).thenReturn(ldapConnection); testee = new LdapAuthenticationFilter(ldapProperties, connectionFactory); final HttpServletRequest request = requestWithAuthorizationHeader(); when(request.getServletPath()).thenReturn("/foo"); final FilterChain filterChain = mock(FilterChain.class); testee.doFilter(request, response, filterChain); verify(filterChain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); }
@Test public void shouldNotApplyFilterToNotAuthenticatedUser() throws IOException, ServletException, GeneralSecurityException, LDAPException { final LdapProperties ldapProperties = ldapProperties("someHost", 389, singletonList("someBaseDn"), null, "someRdnIdentifier", singletonList("/internal"), StartTLS, WHITELISTED_PATH); final LdapConnectionFactory connectionFactory = mock(LdapConnectionFactory.class); final LDAPConnection ldapConnection = someLdapConnectionReturning(AUTHORIZATION_DENIED); when(connectionFactory.buildLdapConnection()).thenReturn(ldapConnection); testee = new LdapAuthenticationFilter(ldapProperties, connectionFactory); final HttpServletRequest request = requestWithAuthorizationHeader(); when(request.getServletPath()).thenReturn("/foo"); final FilterChain filterChain = mock(FilterChain.class); testee.doFilter(request, response, filterChain); verify(filterChain, never()).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); }
@Test public void shouldApplyFilterToAuthenticatedUserWithAdditionallyConfiguredBaseDn() throws IOException, ServletException, GeneralSecurityException, LDAPException { // given final LdapProperties ldapProperties = ldapProperties("someHost", 389, asList("exceptionBaseDn", "successBaseDn"), null, "someRdnIdentifier", singletonList("/internal"), StartTLS, WHITELISTED_PATH); final LdapConnectionFactory connectionFactory = mock(LdapConnectionFactory.class); final LDAPConnection ldapConnection = someLdapConnectionReturningSuccessOrThrowingBindException("successBaseDn", "exceptionBaseDn"); when(connectionFactory.buildLdapConnection()).thenReturn(ldapConnection); testee = new LdapAuthenticationFilter(ldapProperties, connectionFactory); // when final HttpServletRequest request = requestWithAuthorizationHeader(); when(request.getServletPath()).thenReturn("/foo"); final FilterChain filterChain = mock(FilterChain.class); testee.doFilter(request, response, filterChain); // then verify(ldapConnection).bind(contains("exceptionBaseDn"), anyString()); verify(ldapConnection).bind(contains("successBaseDn"), anyString()); verify(filterChain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); }
@Test public void shouldBeUnauthenticatedIfLdapConnectionFails() throws Exception { final LDAPConnection ldapConnection = someLdapConnectionReturning(SERVER_DOWN); when(ldapConnectionFactory.buildLdapConnection()).thenReturn(ldapConnection); testee.doFilter(requestWithAuthorizationHeader(), response, mock(FilterChain.class)); assertUnauthorized(); }