簡體   English   中英

LDAP:錯誤代碼 21 - XXXActive:值 #0 根據語法無效 - spring-data-ldap

[英]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 中找到的唯一示例是自定義存儲庫(不是帶有@EnableLdapRepositoriesLdapRepository接口)和轉換器。

是否可以? 如何?

最好的祝福,
亞歷山大。

更新我已經調試了它 - 調試時我跨過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) conversionServiceorg.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM