[英]Custom Spring UserDetailsService not called
我正在嘗試為當前登錄的用戶添加一些自定義數據,所以我發現我可以實現我自己的 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();
}
沒有任何效果......我嘗試以多種方式檢索用戶信息:
在服務中(我收到無效的轉換錯誤):
認證身份驗證 = SecurityContextHolder.getContext().getAuthentication(); (LoggedInUser) authentication.getPrincipal()
知道為什么它不起作用嗎? 我的 impl 類是否在其他地方被默認覆蓋? 我試圖查看日志(logging.level.org.springframework.security=TRACE)但沒有運氣:/我可以登錄,這工作正常,只是主體數據總是只有用戶名字符串而不是我的班級。
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.