问题是:我有一个Auth服务器(春季安全性)和一个资源服务器,资源服务器无法正确获取主体用户。
Spring Boot版本:2.0.7 春季云版本:Finchley.SR2
首先,我去从Auth服务器获取访问令牌,这是成功的。 然后,我使用令牌发布资源服务器,资源服务器的控制器可以获取主体。 但是,主体是字符串,而不是UserDetails对象。
这样的Auth Server网络安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MaliUserDetailsService maliUserDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(maliUserDetailsService).passwordEncoder(passwordEncoder());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
身份验证服务器UserDetailsService:
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return user;
}
资源服务器控制器:
@GetMapping("/test")
public String test(Authentication authentication) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
return "hello " + userDetails.getUsername();
}
当我发布到资源服务器时,它抛出异常:
java.lang.ClassCastException: class java.lang.String cannot be cast to class org.springframework.security.core.userdetails.UserDetails (java.lang.String is in module java.base of loader 'bootstrap'; org.springframework.security.core.userdetails.UserDetails is in unnamed module of loader 'app')
================ 然后我尝试更改为这样的控制器代码:
@GetMapping("/test")
public String test(Authentication authentication) {
return "hello " + authentication.getPrincipal().toString();
}
结果是“ hello admin”。 (管理员是我的用户名)
为什么控制器中的主体是字符串而不是UserDetails Object?解决方法。