【发布时间】:2021-08-27 22:35:46
【问题描述】:
我正在使用 spring security + spring JWT + Spring JPA 来验证用户。我有一个休息端点 /authenticate 通过身份验证管理器对用户进行身份验证。 Spring security createAuthenticationToken() 调用 loadByUserName(String UserName)。但是当我调试它的打印 NONE_PROVIDED 看我下面的代码
@SpringBootApplication
@EnableJpaRepositories(basePackageClasses=UsersRepo.class)
@ComponentScan(basePackages = {"com.test.ws"})
public class TestWebApp{
public static void main(String[] args) {
SpringApplication.run(TestWebApp.class, args);
}
}
控制器类
@RestController
public class HelloResource {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
UserDeatilService userDeatilService;
@Autowired
JwtUtils jwtUtils;
@RequestMapping(value="/authenticate",method=RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody Users authenticationRequest) throws Exception{
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword()));
final UserDetails userDetails=userDeatilService.loadUserByUsername(authenticationRequest.getUsername());
final String jwt=jwtUtils.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(jwt));
}
服务类
@Service
public class UserDeatilService implements UserDetailsService{
@Autowired
UsersRepo userRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("inside loadUserByUsername::"+username);
Optional<Users> user=userRepo.findByUserName(username);
user.orElseThrow(()->new UsernameNotFoundException("Not found: "+username));
return user.map(MyUserDetail::new).get();
}
}
安全配置器
@EnableWebSecurity
public class Securityconfigurer extends WebSecurityConfigurerAdapter {
@Autowired
private UserDeatilService userDeatilService;
/*@Autowired
private JwtRequestFilter jwtRequestFilter;*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDeatilService);
}
//Dont manage session
@Override
protected void configure(HttpSecurity http) throws Exception{
//http.csrf().disable().authorizeRequests().antMatchers("/h2-console/**").hasAnyRole("h2").antMatchers("/authenticate").permitAll().anyRequest().authenticated();
/*.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);*/
http.authorizeRequests().antMatchers("/admin").hasRole("ADMIN").antMatchers("/authenticate").hasAnyRole("ADMIN","USER").antMatchers("/").permitAll().and().formLogin();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
// TODO Auto-generated method stub
return super.authenticationManagerBean();
}
存储库
@Repository
public interface UsersRepo extends JpaRepository<Users,Integer>{
Optional<Users> findByUserName(String username);
}
MyUesrDetails
public class MyUserDetail implements UserDetails{
private String username;
private String password;
private boolean active;
private List<GrantedAuthority> authorities;
public MyUserDetail(Users user) {
this.username=user.getUsername();
this.password=user.getPassword();
this.active=user.isActive();
this.authorities=Arrays.stream(user.getRoles().split(",")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
}
public MyUserDetail() {
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return authorities;
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return password;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return username;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return active;
}}
【问题讨论】:
-
你在哪里实现了 Spring 的 UserDetailsService ? Spring 将尝试从它的 UserDetailsService 接口调用 loadUserByUsername。您必须实现该接口并在安全配置中设置为用户详细信息服务。在那里覆盖 loadUserByUsername 并编写逻辑以通过您从 Authenticationmanager 传递的用户名加载用户
标签: java spring spring-boot spring-security