2017-09-13 2 views
0

OSS에서 실행중인 openldap이 있습니다 (프로덕션으로 갈 때 IPOS를 실행하는 centos로 이동하지만).Openldap Spring 통합 : 나쁜 인증서

단일 홈 컨트롤러, 스프링 보안 및 ldap 스타터 이외의 간단한 스프링 부팅 응용 프로그램.

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-security</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.ldap</groupId> 
    <artifactId>spring-ldap-core</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-ldap</artifactId> 
</dependency> 
<dependency> 
    <groupId>com.unboundid</groupId> 
    <artifactId>unboundid-ldapsdk</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-test</artifactId> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>org.springframework.security</groupId> 
    <artifactId>spring-security-test</artifactId> 
    <scope>test</scope> 
</dependency> 

뿐만 아니라 종속성을 다음과 같이 내가 구성 클래스가 위 : 다음과 같이 폼은 의존성이

# m.com 
dn: dc=m,dc=com 
objectClass: dcObject 
objectClass: organization 
o: M 
dc: m 

# users, m.com 
dn: ou=users,dc=m,dc=com 
objectClass: organizationalUnit 
ou: users 

# taylorj, users, m.com 
dn: uid=taylorj,ou=users,dc=m,dc=com 
objectClass: top 
objectClass: account 
objectClass: posixAccount 
cn: Jonathan Taylor 
uid: taylorj 
uidNumber: 1 
gidNumber: 1 
homeDirectory: /home/taylorj 
userPassword:: e1NTSEF9UVNVNDBOdlh1bkJqNkhGeVUwekVVYXlNb2RidTErekg= 
:

@Configuration 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
      .anyRequest().fullyAuthenticated() 
      .and().formLogin(); 
    } 

    @Override 
    public void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.ldapAuthentication() 
      .userDnPatterns("uid={0},ou=users") 
      .groupSearchBase("ou=groups") 
      .contextSource(contextSource()) 
      .passwordCompare() 
      .passwordEncoder(new LdapShaPasswordEncoder()) 
      .passwordAttribute("userPassword");  
    } 

    @Bean 
    public DefaultSpringSecurityContextSource contextSource() { 
      return new DefaultSpringSecurityContextSource(Arrays.asList("ldap://localhost:389/"), "dc=m,dc=com"); 
    } 
} 

내 LDAP 디렉토리는 매우 간단합니다, 다음이

스프링 응용 프로그램을 실행하면 LDAP에 연결되고 LDAP 서버에서 reuests가 표시되는 것을 볼 수 있습니다. 검색을 확인하고 결과를 반환 한 다음 사용에 CMP를 할 수 있습니다. rPassword 속성은, 그러나, LDAP는 오류 코드 5 (LDAP_COMPARE_FALSE)을 반환하고 봄에 나는 다음과 같은 예외를 참조하십시오

2017-09-13 15:52:13.315 DEBUG 92002 --- [nio-8132-exec-3] o.s.s.l.a.LdapAuthenticationProvider  : Processing authentication request for user: taylorj 
2017-09-13 15:52:13.317 DEBUG 92002 --- [nio-8132-exec-3] o.a.c.loader.WebappClassLoaderBase  :  findResources(jndi.properties) 
2017-09-13 15:52:13.330 DEBUG 92002 --- [nio-8132-exec-3] o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://localhost:389/dc=m,dc=com' 
2017-09-13 15:52:13.339 DEBUG 92002 --- [nio-8132-exec-3] .s.s.l.a.PasswordComparisonAuthenticator : Performing LDAP compare of password attribute 'userPassword' for user 'uid=taylorj,ou=users' 
2017-09-13 15:52:13.340 DEBUG 92002 --- [nio-8132-exec-3] o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://localhost:389/dc=m,dc=com' 
2017-09-13 15:52:13.342 DEBUG 92002 --- [nio-8132-exec-3] o.s.b.f.s.DefaultListableBeanFactory  : Returning cached instance of singleton bean 'delegatingApplicationListener' 
2017-09-13 15:52:13.342 DEBUG 92002 --- [nio-8132-exec-3] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials 

org.springframework.security.authentication.BadCredentialsException: Bad credentials 
    at org.springframework.security.ldap.authentication.PasswordComparisonAuthenticator.authenticate(PasswordComparisonAuthenticator.java:114) ~[spring-security-ldap-4.2.3.RELEASE.jar:4.2.3.RELEASE] 

나는 어떤 종류의 것으로 보인다 내가 잘못 뭘하는지 정말 모르겠어요를 내부 스프링 문제로 인해 암호 비교가 실패합니다.

아이디어가 있으십니까?

UPDATE

나는 봄이 제공하는 LDIF로 다시 복귀하고, 그 괜찮 았는데. 좌절감을 느낀 다음 스프링 LDIF가 제공하는 사용자 벤의 암호를 변경하기 위해 다음을 실행했습니다

ldappasswd -x -D "cn = admin, dc = m, dc = com"-W -S "uid = OU = 사람들, DC = m, DC = COM "

이 명령을 실행 한 후, 내 로그인은 더 이상 스프링에서 제공하는 LDIF 보면

작동하지 않습니다 :

dn: uid=ben,ou=people,dc=m,dc=com 
objectclass: top 
objectclass: person 
objectclass: organizationalPerson 
objectclass: inetOrgPerson 
cn: Ben Alex 
sn: Alex 
uid: ben 
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ= 

것 같다 설정하는 SHA로 암호, 내가 ldappasswd를 실행하면 Salted SHA (SSHA)로 끝납니다. 문서에서 볼 수있는 한, 스프링 구현은 SHA와 SSHA를 모두 처리해야합니다.

아직 어떤 일이 벌어지고 있는지 확실하지 않습니다.

답변

0

봄 보안에는 버그가 있습니다.

org.springframework.security.ldap.authentication. PasswordComparisonAuthenticator setPasswordEncoder 방법

초기 라인 : usePasswordAttrCompare 경우 거짓 로 설정이 이것으로

public void setPasswordEncoder(Object passwordEncoder) { 
    if (passwordEncoder instanceof PasswordEncoder) { 
     this.usePasswordAttrCompare = false; 
     setPasswordEncoder((PasswordEncoder) passwordEncoder); 
     return; 
    } 

암호 인코더는 입력되는 PasswordEncoder이다. 이 문제는이 플래그가 false로 설정된 경우으로 변경되어 LDAP와 암호 비교를 수행하는 것으로 바뀌 었습니다. 암호는 SSHA로 저장되기 때문에 Spring은 SHA Salt를 미리 알 수 없기 때문에 분명히 일치하지 않는 암호의 SHA1 버전을 보냅니다.isPasswordValid 비교를 위해 평문 암호 해시 암호를 모두 취 수 있으므로 반면하여 인증에

()

else if (isLdapPasswordCompare(user, ldapTemplate, password)) { 
     return user; 
} 

인해 LdapShaPasswordEncoder가 구현되는 방식은 상기 인코딩 기능은 단지 평문 암호를 얻어 소금을 추출하여 SSHA 변이체를 계산하십시오.

나는 수정 다음과 같이 setPasswordEncoder 기능 (I 돌아가서 어떤 점에서 적절하게 할 것) : 우리는 우리가 항상 isPasswordValid 방법으로 폴백하는 LdapShaPasswordEncoder이있는 경우

if (passwordEncoder instanceof PasswordEncoder) { 
    if(passwordEncoder instanceof org.springframework.security.authentication.encoding.LdapShaPasswordEncoder) { 
     this.usePasswordAttrCompare = true; 
    } else { 
     this.usePasswordAttrCompare = false; 
    } 
    setPasswordEncoder((PasswordEncoder) passwordEncoder); 
    return; 
} 

하는 일반 텍스트, SHA 및 SSHA 암호를 처리합니다.

스프링 보안을 재구성하고 새로운 jar에 대한 코드를 다시 작성하면 정상적으로 작동합니다. 이제는 더 좋은 방법을 찾아서 Spring에 가져 와서 끌어 당깁니다.