0

AD를 통해 로그인 한 사용자가 있는데, 이제 해당 사용자의 정보를 얻고 싶습니다.자바 스프링이 Active Directory에서 속성을 가져옵니다. UserDetails

@RequestMapping(value={"/secure/test"}, method=RequestMethod.GET) 
public ResponseEntity<?> getSecureTest(HttpServletRequest request) { 
    String str = "Test Response"; 

    request.getSession().setAttribute("testVar", "SessionVariable"); 

    Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
    UserDetails userDetails = (UserDetails) authentication.getPrincipal(); 
    if (!(authentication instanceof AnonymousAuthenticationToken)) { 
     String currentUserName = authentication.getName(); 
     str = str + "\n -- " + currentUserName + "\n\n"; 
     str = str + userDetails.getUsername(); // matches authentication.getName() 
     return new ResponseEntity<>(str, HttpStatus.OK); 
    } else { 
     str = str + "failed auth"; 
     return new ResponseEntity<>(str, HttpStatus.UNAUTHORIZED); 
    } 
} 

내가 인증을받을 수 있도록, UserDetails 객체에서 할 수 있지만, 내가 믿는 나오는 구현은 LdapUserDetailsImpl

https://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/ldap/userdetails/LdapUserDetailsImpl.html

이 있습니다 : 여기에 내가 함께 연주하고 샘플 테스트 엔드 포인트입니다 "getAttribute"또는 무엇이든을 좋아하는 어떤 메소드도없는 것처럼 보입니다. "mail"이나 "telephoneNumber"와 같은 광고 속성 중 하나를 얻으려면 어떻게해야합니까?

편집 :

그래서, 그냥이 LdapUserDetailsImpl 확장 "제목"속성을 추출하는 시도 :

public class CustomUserDetails extends LdapUserDetailsImpl { 

    private String title; 

    public void setTitle(String title) { 
     this.title = title; 
    } 
    public String getTitle() { 
     return this.title; 
    } 
} 

을 그리고 나는 LdapUserDetailsMapper 확장 : 내 컨트롤러에서

public class CustomDetailsContextMapper extends LdapUserDetailsMapper { 

    @Override 
    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) { 
     LdapUserDetailsImpl ldapUserDetailsImpl = (LdapUserDetailsImpl) super.mapUserFromContext(ctx, username, authorities); 
     CustomUserDetails customUserDetails = new CustomUserDetails(); 
     customUserDetails.setTitle(ctx.getStringAttribute("title")); 
     return customUserDetails; 
    } 
} 

을 이 객체를 가져 오려고합니다.

CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); 

하지만 캐스팅 오류가 발생합니다 ... 무엇이 누락 되었습니까?

WebSecurityConfigurerAdapter는이 물건을 가지고

@Override 
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception { 
    authManagerBuilder.authenticationProvider(activeDirectoryLdapAuthenticationProvider()); 
    authManagerBuilder.userDetailsService(userDetailsService()); 
} 

@Bean 
public AuthenticationManager authenticationManager() { 
    return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProviderES())); 
} 
@Bean 
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() { 
    ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(ldapdomain, ldapurl); 
    provider.setConvertSubErrorCodesToExceptions(true); 
    provider.setUseAuthenticationRequestCredentials(true); 

    return provider; 
} 

답변

1

당신은 스프링 LDAP를 확장하여 자신의 사용자 정보 매퍼를 구현할 수 있습니다.

package example.active.directory.authentication; 

import org.springframework.ldap.core.DirContextOperations; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper; 

import java.time.LocalDateTime; 
import java.time.OffsetDateTime; 
import java.time.format.DateTimeFormatter; 
import java.util.Arrays; 
import java.util.Collection; 

public class CustomUserMapper extends LdapUserDetailsMapper{ 

    @Override 
    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities){ 

     UserDetails details = super.mapUserFromContext(ctx, username, authorities); 
     String[] changedValues = ctx.getStringAttributes("whenchanged"); 
     /// Do something here, like map to your custom UserDetails object. 
     return details;   
    } 
} 

해당 방법에서 중단 점을 설정하면 디버거에서 사용할 수있는 모든 다른 속성을 탐색 할 수 있어야합니다.

이 내가 준 다른 답변과 유사합니다 Update users informations during login against LDAP AD using Spring

+0

이 경우, 당신은 바로, 당신이 ctx.getStringAttribute 나가거나 어떤 물건에 해당 필드를 CustomUserMapper에 대한 몇 가지 추가 필드를 만든 다음 할당 할 필요가있다 ? 나중에 컨트롤러에서 어떻게 사용합니까? 이 특정 유형으로 전송하면됩니까? – MichaelB

+0

사용자 지정 'UserDetails'개체에 추가 필드 (필요한 경우)를 추가해야합니다. 그런 다음 LDAP UserDetails 매퍼를 확장하는 매퍼가 필요에 따라 UserDetails 객체의 필드를 채 웁니다. 그러면 컨트롤러에서 필요에 따라 SecurityContext에서 UserDetails 버전을 가져올 수 있습니다. – MathanMV

+0

내 업데이트를 볼 수 있습니까? 나는 모든 UserDetails 클래스를 확장하여 속성을 캡처하려고 시도했지만 아직 작동하지 않습니다. – MichaelB