[英]LDAP: error code 21 - XXXActive: value #0 invalid per syntax - spring-data-ldap
我將 spring-data-ldap 與 OOM 和我自己的包含 boolean 屬性的模式一起使用。 當我嘗試在 openLDAP 中存儲一個值或從中讀取一個值時,出現異常
javax.naming.directory.InvalidAttributeValueException:[LDAP:錯誤代碼 21 - XXXActive:值 #0 根據語法無效]
這是我的架構(實際的客戶前綴已替換為“XXX”):
dn: cn=XXX,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: XXX
olcAttributeTypes: ( 1.3.6.1.4.1.42691910.1.1.1.1 NAME 'XXXActive'
DESC 'whether the subscriber has been activated (default false, after self-registration)'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.42691910.1.1.1.2 NAME 'XXXLocale'
DESC 'the locale in which he wants to receive emails'
EQUALITY caseExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
olcAttributeTypes: ( 1.3.6.1.4.1.42691910.1.1.1.7 NAME 'XXXQueryFreshnessDate'
DESC 'freshness date ...'
EQUALITY generalizedTimeMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
SINGLE-VALUE )
olcObjectClasses: ( 1.3.6.1.4.1.42691910.1.1.2.1 NAME 'XXXSubscriber'
DESC 'a subscriber for ...'
SUP top
STRUCTURAL
MUST ( uid $ userPassword )
MAY ( XXXActive $ XXXLocale $ XXXQueryFreshnessDate $ telephoneNumber ) )
這是我的實體 class:
import lombok.*;
import org.springframework.ldap.odm.annotations.*;
import javax.naming.Name;
import java.io.Serializable;
import java.util.Date;
@Getter
@Setter
@Entry(objectClasses = {"XXXSubscriber", "top"})
@EqualsAndHashCode
@Builder
@AllArgsConstructor
@NoArgsConstructor
public final class XXXSubscriber implements Serializable {
@Id
private Name dn;
@Attribute(name = "uid")
@DnAttribute(value = "uid", index = 3)
private String email;
@Transient
@DnAttribute(value = "dc", index = 0)
private String env;
@Transient
@DnAttribute(value = "dc", index = 1)
private String application;
@Transient
@DnAttribute(value = "ou", index = 2)
private String orga;
@Attribute(name = "telephoneNumber")
private String phone;
@Attribute(name = "XXXActive", syntax="1.3.6.1.4.1.1466.115.121.1.7") //TODO throws an error due to invalid syntax false/FALSE
private boolean active;
@Attribute(name = "XXXQueryFreshnessDate", syntax = "1.3.6.1.4.1.1466.115.121.1.24") //TODO doesn't work either
private Date queryFreshnessDate;
@Attribute(name = "XXXLocale")
private String locale;
@Attribute(name = "userPassword", type = Attribute.Type.BINARY)
private byte[] password;
}
以及相應的 Repo class(通過@org.springframework.data.ldap.repository.config.EnableLdapRepositories()
注冊):
import org.springframework.data.ldap.repository.LdapRepository;
public interface XXXSubscriberRepo extends LdapRepository<XXXSubscriber> {
XXXSubscriber findOneByEmail(String email);
XXXSubscriber findOneByEmailAndActive(String email, boolean active);
}
這是來自 ldif 的示例條目:
dn: uid=somebody@example.org,ou=subscribers,dc=applications,dc=test,dc=example,dc=org
objectclass: top
objectclass: XXXSubscriber
uid: somebody@example.org
telephoneNumber: 004940123456789
XXXActive: TRUE
XXXLocale: en
userPassword: {SCRYPT}$e0801$9KXJwk7Q0kFzj07LWKef4TgGmPll0sr1hWxL6kMAQzuluW/87EyaQ4lLkWHNdUInF1GMkm7DAefsa+wUOlMGJg==$3aCwqyWYcS70p6Ib1k/Wh7gKsyZwYq/D3ynZpUUvIfM=
XXXQueryFreshnessDate: 20221108164632.123Z
是否有可能使用org.springframework.data.ldap.repository.LdapRepository
,但為此 class 注冊正確的轉換器,以便它可以正確處理 boolean 值? 默認情況下,boolean 值被轉換為“true”/“false”,但 LDAP 似乎期望“TRUE”/“FALSE”( MATCH booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
)。
順便說一句,我很確定 Date XXXQueryFreshnessDate
( MATCH generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
) 需要進行相應的轉換。
我在 inte.net 中找到的唯一示例是自定義存儲庫(不是帶有@EnableLdapRepositories
的LdapRepository
接口)和轉換器。
是否可以? 如何?
最好的祝福,
亞歷山大。
更新我已經調試了它 - 調試時我跨過org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper#populateSingleValueAttribute
- 它調用org.springframework.ldap.odm.typeconversion.impl.ConversionServiceConverterManager#convert(Object source, String syntax, Class<T> toClass)
with
source
:假syntax
:“1.3.6.1.4.1.1466.115.121.1.7”toClass
: java.lang.String
(.) 它試圖將給定的 Boolean 轉換為字符串。
(:) 它完全忽略了語法:
@Override
public <T> T convert(Object source, String syntax, Class<T> toClass) {
return conversionService.convert(source, toClass);
}
(i) conversionService
是org.springframework.core.convert.support.DefaultConversionService
類型。
我設法通過將自己的ConversionService
/ ConversionServiceConverterManager
連接到 LdapTemplate 來實現這一點,如下所示:
@Bean
public DefaultConversionService myObjectDirectoryMapper(LdapTemplate ldapTemplate) {
DefaultObjectDirectoryMapper objectDirectoryMapper = (DefaultObjectDirectoryMapper) ldapTemplate.getObjectDirectoryMapper();
DefaultConversionService conversionService = new DefaultConversionService();
// own implementations
conversionService.addConverter(new BooleanToStringConverter());
conversionService.addConverter(new StringToBooleanConverter());
// implementations from https://mvnrepository.com/artifact/org.ldaptive/ldaptive-beans/2.1.1
conversionService.addConverter(new StringToZonedDateTimeConverter());
conversionService.addConverter(new ZonedDateTimeToStringConverter());
ConversionServiceConverterManager converterManager = new ConversionServiceConverterManager(conversionService);
objectDirectoryMapper.setConverterManager(converterManager);
return conversionService;
}
與我的轉換器類
class BooleanToStringConverter
implements org.springframework.core.convert.converter.Converter<Boolean, String> {
@Override
public String convert(Boolean source) {
return source.toString().toUpperCase();
}
}
和
class StringToBooleanConverter
implements org.springframework.core.convert.converter.Converter<String, Boolean> {
@Override
public Boolean convert(String source) {
return Boolean.parseBoolean(source.toLowerCase());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.