【问题标题】:Custom Spring UserDetailsService not called未调用自定义 Spring UserDetailsS​​ervice
【发布时间】:2019-06-01 11:35:31
【问题描述】:

我正在尝试为当前登录的用户添加一些自定义数据,所以我发现我可以实现自己的 UserDetailsS​​ervice 并将其插入 Spring,但它从未被调用,我总是将 Principal 作为用户名字符串。

我已经实现了 UserDetailsS​​ervice:

@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 {
...
}

并尝试通过多种方式在 config (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 的控制器中我得到 null
  2. 在服务中(我收到无效的转换错误):

    身份验证身份验证 = SecurityContextHolder.getContext().getAuthentication(); (LoggedInUser) authentication.getPrincipal()

知道为什么它不起作用吗?我的 impl 类是否在其他地方被默认覆盖?我试图查看日志(logging.level.org.springframework.security=TRACE)但没有运气:/ 我可以登录,效果很好,只是主体数据总是只有用户名字符串,而不是我的班级。

【问题讨论】:

  • 您是否保护了您的端点?
  • 什么是CustomAuthenticationProvider?显示您的代码。
  • 可能会弄错,但我认为您的 userDetailsS​​ervice 没有被调用,因为您定义了自定义身份验证提供程序。它完成了包括寻找用户在内的所有工作。
  • @rbiggy 您能否分享您的代码,尤其是您的安全配置?我在同一个问题上苦苦挣扎:CustomAuthenticationProvider 不起作用(authenticate() 方法没有被调用)并且 UserDetailsS​​ervice 也没有被调用..

标签: java spring spring-boot spring-security userdetailsservice


【解决方案1】:

ILya Cyclone 的评论是找出问题所在的关键,在再次检查 CustomAuthenticationProvider 后,我注意到在返回数据时您可以指定 Principal,而不必只是用户名,但您可以添加您的在那里自定义UserDetails,因为没有调用自定义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);
  }
}

【讨论】:

  • 我知道,但是有时间限制,我需要再等20个小时才能接受
猜你喜欢
  • 2016-03-09
  • 2013-02-11
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 2018-12-06
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多