Пользовательский Spring UserDetailsService не вызывается - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь добавить некоторые пользовательские данные для текущего пользователя, вошедшего в систему, поэтому я обнаружил, что могу реализовать свой собственный UserDetailsService и просто подключить его к Spring, но он никогда не вызывается, я всегда получаю Principal как просто строку имени пользователя.

У меня есть реализация UserDetailsService:

@Service
public class UserDetailServiceImpl implements UserDetailsService {

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    ...
  }
}

моя реализация UserDetails:

import org.springframework.security.core.userdetails.User;

public class LoggedInUser extends User {
...
}

и попытался установить его в конфигурации (SecurityConfiguration) несколькими способами:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
      @Autowired
      private CustomAuthenticationProvider customAuthProvider;
      @Autowired
      private UserDetailsService userDetailServiceImpl;
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthProvider);
        auth.userDetailsService(userDetailServiceImpl).passwordEncoder(passwordService.getPasswordEncoder());
      }
...
}

или

@Autowired
  protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthProvider);
    auth.userDetailsService(userDetailServiceImpl).passwordEncoder(passwordService.getPasswordEncoder());
  }

или

@Override
  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailServiceImpl();
  }

и ничего не работает ... Я попытался получить информацию о пользователе несколькими способами:

  1. в контроллере с @AuthenticationPrincipal, где я получаю ноль
  2. в службе (я получаю неверную ошибку приведения):

    Аутентификация аутентификации = SecurityContextHolder.getContext (). GetAuthentication (); (LoggedInUser) authentication.getPrincipal ()

Есть идеи, почему это не работает? Мой класс impl переопределяется по умолчанию в другом месте? Я пытался посмотреть в журналах (logging.level.org.springframework.security = TRACE), но не повезло: / Я могу войти, это работает нормально, только основные данные всегда только имя пользователя String, а не мой класс.

1 Ответ

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

Комментарий Ильи Циклона был тем, что было ключом к выяснению того, что было не так, после проверки CustomAuthenticationProvider снова я заметил, что при возврате данных вы можете указать Principal, который не должен быть только именем пользователя, но вы можете добавить свой custom UserDetails там и из-за этого custom UserDetailsService не вызывается, что было моей ошибкой, предполагая, что он будет вызываться всегда.

Таким образом, в конечном итоге этого достаточно, чтобы пользовательский AuthenticationProvider имел пользовательский UserDetails:

@Service
public class CustomAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private UserService userService;

  @Autowired
  private PasswordService passwordService;

  @Override
  public Authentication authenticate(Authentication auth) throws AuthenticationException {
    String username = auth.getName();
    String password = auth.getCredentials().toString();

    User user = userService.getUserWithPermissionsByName(username);
    if (user == null) {
      throw new BadCredentialsException("invalid_username_or_pass");
    }

    if (!passwordService.passwordsMatch(password, user.getPassword())) {
      throw new BadCredentialsException("invalid_username_or_pass");
    }

    String[] permissions = user.getPermissions().stream().map((p) -> p.getName()).toArray(String[]::new);
    List<GrantedAuthority> grantedAuths = AuthorityUtils.createAuthorityList(permissions);
    return new UsernamePasswordAuthenticationToken(new LoggedInUser(user.getName(), user.getPassword(), true, true, true, true, grantedAuths, user.getId()),
        password, grantedAuths);
  }

  @Override
  public boolean supports(Class<?> auth) {
    return auth.equals(UsernamePasswordAuthenticationToken.class);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...