@Bean @ConditionalOnMissingBean(UserProvider.class) public UserProvider userProvider() { return () -> { final HttpServletRequest request = HttpServletRequestHolder.get(); final Optional<Credentials> credentials = Credentials.readFrom(request); final boolean isAdmin = true; // "admin".equals(username); return new SimpleFeatureUser((credentials.isPresent() ? credentials.get().getUsername() : null), isAdmin); }; }
/** * Read username and password from the request's {@code Authorization} header and create a {@code Credentials} * object. Requires authorization header to be base64 encoded. * * @param request incoming http request * @return {@code Optional} with parsed {@code Credentials} if {@code Authorization} header and credentials * are present, {@code Optional.empty} otherwise. */ public static Optional<Credentials> readFrom(HttpServletRequest request) { String authorizationHeader = request.getHeader("Authorization"); if (!StringUtils.isEmpty(authorizationHeader)) { String credentials = authorizationHeader.substring(6, authorizationHeader.length()); String[] decodedCredentialParts = new String(Base64Utils.decode(credentials.getBytes())).split(":", 2); if (!decodedCredentialParts[0].isEmpty() && !decodedCredentialParts[1].isEmpty()) { return Optional.of(new Credentials(decodedCredentialParts[0], decodedCredentialParts[1])); } } return Optional.empty(); } }
@Test public void shouldReturnCorrectCredentialsIfPasswordContainsColons() { // given mockHttpServletRequestWithAuthentication("user:pass:word"); // when final Optional<Credentials> credentials = Credentials.readFrom(httpServletRequest); // then assertThat(credentials.isPresent(), is(true)); assertThat(credentials.get().getUsername(), is("user")); assertThat(credentials.get().getPassword(), is("pass:word")); } }
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(); }
@Override protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException { Optional<Credentials> optionalCredentials = readFrom(request); if (optionalCredentials.isPresent()) { final Optional<HttpServletRequest> authRequest = tryToGetAuthenticatedRequest(request, optionalCredentials.get()); if (authRequest.isPresent()) { filterChain.doFilter(authRequest.get(), response); } else { unauthorized(response); } } else { unauthorized(response); } }
String userDnFrom(final Credentials credentials, String baseDN) { return format("%s=%s,%s", ldapProperties.getRdnIdentifier(), credentials.getUsername(), baseDN); }
@Test public void shouldBeAbleToReadCredentialsFromRequest() { // given mockHttpServletRequestWithAuthentication("someUsername:somePassword"); // when final Optional<Credentials> credentials = Credentials.readFrom(httpServletRequest); // then assertThat(credentials.isPresent(), is(true)); assertThat(credentials.get().getUsername(), is("someUsername")); assertThat(credentials.get().getPassword(), is("somePassword")); }
@Test public void shouldReturnEmptyCredentialsIfHeaderDoesNotExist() { // when final Optional<Credentials> credentials = Credentials.readFrom(httpServletRequest); // then assertThat(credentials.isPresent(), is(false)); }
@Test public void shouldReturnEmptyCredentialsIfUsernameNotSet() { // given mockHttpServletRequestWithAuthentication(":password"); // when final Optional<Credentials> credentials = Credentials.readFrom(httpServletRequest); // then assertThat(credentials.isPresent(), is(false)); }
@Test public void shouldBuildUserDnFromCredentials() { final String userDn = testee.userDnFrom(new Credentials("user", "password"), "someBaseDn"); assertThat(userDn).isEqualTo("someRdnIdentifier=user,someBaseDn"); }
@Test public void shouldReturnEmptyCredentialsIfPasswordNotSet() { // given mockHttpServletRequestWithAuthentication("someUsername:"); // when final Optional<Credentials> credentials = Credentials.readFrom(httpServletRequest); // then assertThat(credentials.isPresent(), is(false)); }