java.lang.String нельзя привести к org.springframework.security.ldap.userdetails.LdapUserDetails - PullRequest
0 голосов
/ 17 января 2019

Мне удалось настроить авторизацию OAuth2 и ldap. Создан пользовательский LdapUser путем реализации LdapUserDetails и CustomUserDetailsContextMapper путем реализации UserDetailsContextMapper . В конце концов, я получаю токен доступа при авторизации по имени пользователя и паролю Active Directory.

Но проблема в том, что я не могу получить моего текущего зарегистрированного пользователя от SecurityContextHolder.getContext (). GetAuthentication () , как говорится java.lang.String не может быть преобразован в LdapUser

Ниже моей настройки безопасности:

@Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(adAuthenticationProvider())
        .ldapAuthentication()
    .userSearchBase("ldap.searchbase").userSearchFilter("ldap.filter").groupSearchFilter("ldap.groupsearch")
        .contextSource(contextSource())
        .userDetailsContextMapper(userDetailsContextMapper())
        .passwordCompare()
        .passwordEncoder(new LdapShaPasswordEncoder())
        .passwordAttribute("userPassword");
  }

@Bean
public DefaultSpringSecurityContextSource contextSource() {
    return  new DefaultSpringSecurityContextSource(Arrays.asList("ldap.url"), "dc=smth,dc=com");
 }

  @Bean
public ActiveDirectoryLdapAuthenticationProvider adAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("smth.com","ldap.url");
    provider.setConvertSubErrorCodesToExceptions(true);
    provider.setUseAuthenticationRequestCredentials(true);
    provider.setUserDetailsContextMapper(userDetailsContextMapper());
    return provider;
}

@Bean
  public UserDetailsContextMapper userDetailsContextMapper() {
    return new CustomUserDetailsContextMapper();
  }

Пользовательский LdapUser:

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.ldap.userdetails.LdapUserDetails;
import java.util.Collection;

public class LdapUser implements LdapUserDetails
{
    private String commonName;
    private LdapUserDetails ldapUserDetails;

public LdapUser(LdapUserDetails ldapUserDetails) {
    this.ldapUserDetails = ldapUserDetails;
}

@Override
public String getDn() {
    return ldapUserDetails.getDn();
}

@Override
public void eraseCredentials() {

}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return ldapUserDetails.getAuthorities();
}

@Override
public String getPassword() {
    return ldapUserDetails.getPassword();
}

@Override
public String getUsername() {
    return ldapUserDetails.getUsername();
}

@Override
public boolean isAccountNonExpired() {
    return ldapUserDetails.isAccountNonExpired();
}

@Override
public boolean isAccountNonLocked() {
    return ldapUserDetails.isAccountNonLocked();
}

@Override
public boolean isCredentialsNonExpired() {
    return ldapUserDetails.isCredentialsNonExpired();
}

@Override
public boolean isEnabled() {
    return ldapUserDetails.isEnabled();
}
}

CustomUserDetailsContextMapper: Я могу успешно распечатать атрибуты контекста и вижу, что это мой зарегистрированный пользователь

@Configuration
public class CustomUserDetailsContextMapper extends LdapUserDetailsMapper implements UserDetailsContextMapper {
private LdapUser ldapUser = null;
private String commonName;
private Boolean isCity;

@Override
public LdapUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
    Attributes attributes = ctx.getAttributes();
    LdapUserDetails ldapUserDetails = (LdapUserDetails) super.mapUserFromContext(ctx,username,authorities);
    return new LdapUser(ldapUserDetails);
}

@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {

    }
}

А теперь вот как я хочу получить пользовательский LdapUser:

public LdapUser getCurrentLdapUser() {
    org.springframework.security.core.context.SecurityContext securityContext = SecurityContextHolder
            .getContext();
    Authentication authentication = securityContext.getAuthentication();
    LdapUser user = null;
    if (authentication != null) {
            user = ((LdapUser) authentication.getPrincipal());
    }
    return user;
}

После вызова этой функции я получаю ошибку приведения. Когда я пытаюсь получить имя участника, оно возвращается - anonymousUser. Понятия не имею, почему он мне не возвращает LdapUser

1 Ответ

0 голосов
/ 22 января 2019

Хорошо, я получил ответ. Пропустил основные вещи. Поскольку я не настраивал сервер ресурсов ( ResourceServerConfigurerAdapter ), каждый зарегистрированный пользователь Active Directory считается анонимным. Вот почему Security Context возвращал пользователя String вместо моего пользовательского пользователя Ldap.

Вот пример ResourceServerConfig на случай, если кому-то понадобится:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  private static final String RESOURCE_ID = "resource_id";

  @Override
  public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources
    .resourceId(RESOURCE_ID)
    .stateless(false);
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http
    .anonymous().disable()
    .authorizeRequests()
    .antMatchers("/api/**").hasAnyAuthority("Authority_1","Authority_2")
    .and().exceptionHandling().authenticationEntryPoint(new UnauthorizedHandler())
    .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler());
  }

  @Bean
  public AccessDeniedHandler accessDeniedHandler() {
    return new CustomAccessDeniedHandler();
  }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...