LdaptiveProperties.java
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bremersee.data.ldaptive;
import java.time.Duration;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.bremersee.data.ldaptive.transcoder.UserAccountControlValueTranscoder;
import org.ldaptive.ReturnAttributes;
import org.ldaptive.SearchConnectionValidator;
import org.ldaptive.SearchRequest;
import org.ldaptive.SearchScope;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
/**
* The ldap properties.
*
* @author Christian Bremer
*/
@SuppressWarnings({"WeakerAccess"})
@ConfigurationProperties(prefix = "bremersee.ldaptive")
@Validated
@Getter
@Setter
@ToString(exclude = {"bindCredentials"})
@EqualsAndHashCode(exclude = {"bindCredentials"})
@NoArgsConstructor
public class LdaptiveProperties {
/**
* Specifies whether ldap connection should be configured or not.
*/
private boolean enabled = true;
/**
* Specifies whether an ldap user details service should be configured or not.
*/
private boolean authenticationEnabled = false;
/**
* URL to the LDAP(s).
*/
private String ldapUrl = "ldap://localhost:12389";
/**
* Duration of time that connects will block.
*/
@NotNull
private Duration connectTimeout = Duration.ofMinutes(1);
/**
* Duration of time to wait for responses.
*/
@NotNull
private Duration responseTimeout = Duration.ofMinutes(1);
/**
* Duration of time that operations will block on reconnects, should generally be longer than connect timeout.
*/
@NotNull
private Duration reconnectTimeout = Duration.ofMinutes(2);
/**
* Whether to automatically reconnect to the server when a connection is lost. Default is true.
*/
private boolean autoReconnect = true;
@Min(0)
private int reconnectAttempts = 5;
@NotNull
private Duration reconnectBackoffDelay = Duration.ofSeconds(2);
private double reconnectBackoffMultiplier = 1.;
/**
* Whether pending operations should be replayed after a reconnect. Default is true.
*/
private boolean autoReplay = true;
/**
* Connect to LDAP using startTLS.
*/
private boolean useStartTls;
/**
* Name of the trust certificates to use for the SSL connection.
*/
private String trustCertificates;
/**
* Name of the authentication certificate to use for the SSL connection.
*/
private String authenticationCertificate;
/**
* Name of the key to use for the SSL connection.
*/
private String authenticationKey;
/**
* DN to bind as before performing operations.
*/
private String bindDn;
/**
* Credential for the bind DN.
*/
private String bindCredentials;
/**
* Specifies whether the connection should be pooled or not. Default is {@code false}.
*/
private boolean pooled = false;
/**
* Duration to wait for an available connection.
*/
@NotNull
private Duration blockWaitTime = Duration.ofMinutes(1);
/**
* Minimum pool size.
*/
private int minPoolSize = 3;
/**
* Maximum pool size.
*/
private int maxPoolSize = 10;
/**
* Whether to connect to the ldap on connection creation.
*/
private boolean connectOnCreate = true;
/**
* Whether initialize should throw if pooling configuration requirements are not met.
*/
private boolean failFastInitialize = true;
/**
* Whether the ldap object should be validated when returned to the pool.
*/
private boolean validateOnCheckIn = false;
/**
* Whether the ldap object should be validated when given from the pool.
*/
private boolean validateOnCheckOut = false;
/**
* Whether the pool should be validated periodically.
*/
private boolean validatePeriodically = false;
/**
* Validation period.
*/
@NotNull
private Duration validatePeriod = Duration.ofMinutes(30);
/**
* Maximum length of time a connection validation should block.
*/
@NotNull
private Duration validateTimeout = Duration.ofSeconds(5);
@NotNull
private SearchValidatorProperties searchValidator = new SearchValidatorProperties();
/**
* Prune period.
*/
@NotNull
private Duration prunePeriod = Duration.ofMinutes(5);
/**
* Idle time.
*/
@NotNull
private Duration idleTime = Duration.ofMinutes(10);
@NotNull
private UserDetailsProperties userDetails = new UserDetailsProperties();
/**
* Create search connection validator search connection validator.
*
* @return the search connection validator
*/
@NotNull
public SearchConnectionValidator createSearchConnectionValidator() {
return new SearchConnectionValidator(
validatePeriod,
validateTimeout,
searchValidator.getSearchRequest().createSearchRequest());
}
/**
* The search validator properties.
*/
@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
public static class SearchValidatorProperties {
@NotNull
private SearchRequestProperties searchRequest = new SearchRequestProperties();
/**
* The search request properties.
*/
@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
public static class SearchRequestProperties {
private String baseDn;
@NotNull
private SearchFilterProperties searchFilter = new SearchFilterProperties();
private Integer sizeLimit;
private SearchScope searchScope; // = SearchScope.ONELEVEL;
@NotNull
private List<String> returnAttributes = new ArrayList<>();
/**
* Gets the return attributes as array.
*
* @return the return attributes as array
*/
@NotNull
public String[] returnAttributesAsArray() {
if (returnAttributes.isEmpty()) {
return ReturnAttributes.NONE.value();
}
return returnAttributes.toArray(new String[0]);
}
/**
* Create search request.
*
* @return the search request
*/
@NotNull
public SearchRequest createSearchRequest() {
SearchRequest searchRequest = new SearchRequest();
searchRequest.setBaseDn(StringUtils.hasText(getBaseDn()) ? getBaseDn() : "");
if (StringUtils.hasText(getSearchFilter().getFilter())) {
searchRequest.setFilter(getSearchFilter().getFilter());
}
searchRequest.setReturnAttributes(returnAttributesAsArray());
if (getSearchScope() != null) {
searchRequest.setSearchScope(getSearchScope());
}
if (getSizeLimit() != null) {
searchRequest.setSizeLimit(getSizeLimit());
}
return searchRequest;
}
/**
* The search filter properties.
*/
@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
public static class SearchFilterProperties {
private String filter;
}
}
}
/**
* The user details properties.
*/
@Getter
@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor
public static class UserDetailsProperties {
private String userBaseDn;
private String userFindOneFilter = "(&(objectClass=group)(sAMAccountName={0}))";
private SearchScope userFindOneSearchScope = SearchScope.ONELEVEL;
private String userAccountControlAttributeName = UserAccountControlValueTranscoder.ATTRIBUTE_NAME;
private String authorityAttributeName = "memberOf";
private boolean authorityDn = true;
private List<String> authorities = new LinkedList<>();
private Map<String, String> authorityMap = new LinkedHashMap<>();
private String authorityPrefix = "ROLE_";
private String userPasswordAttributeName = "userPassword";
private String userPasswordLabel = "SHA";
private String userPasswordAlgorithm = "SHA";
}
}