【问题标题】:Spring Boot + Security loadByUserName not passing userNameSpring Boot + Security loadByUserName 未通过 userName
【发布时间】: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 的 UserDetailsS​​ervice ? Spring 将尝试从它的 UserDetailsS​​ervice 接口调用 loadUserByUsername。您必须实现该接口并在安全配置中设置为用户详细信息服务。在那里覆盖 loadUserByUsername 并编写逻辑以通过您从 Authenticationmanager 传递的用户名加载用户

标签: java spring spring-boot spring-security


【解决方案1】:

看起来一切都在您的例外中得到了解释:

通过字段'userDetilService'表示的不满足的依赖关系;

嵌套异常是 org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为 'userDeutilService' 的 bean 时出错:通过字段 'userRepo' 表达的依赖关系不满足;

嵌套异常是 org.springframework.beans.factory.BeanCreationException:在 BarsaminWebApplication 上声明的 @EnableJpaRepositories 中定义的 com.barsamin.ws.repo.UsersRepo 中创建名称为“usersRepo”的 bean 时出错:

init 方法调用失败;嵌套异常是 java.lang.IllegalArgumentException:

无法为公共抽象方法创建查询java.util.Optional com.barsamin.ws.repo.UsersRepo.findByUserName(java.lang.String)!

找不到类型用户的属性用户名!您指的是“用户名”吗?

【讨论】:

  • 那么这里的错误是什么
  • 见上面的粗体字
【解决方案2】:

正如例外所说:

“未找到类型 Users 的属性 userName!您的意思是 'username'”。

在您的存储库中,您声明了一个名为 findByUserName 的函数,并且应该是 findByUsername,因为您将 MyUserDeatails 的这个属性定义为用户名而不是用户名,区分大小写。

【讨论】:

    猜你喜欢
    • 2020-02-07
    • 1970-01-01
    • 2016-09-10
    • 2015-07-12
    • 2018-03-29
    • 1970-01-01
    • 2020-08-28
    • 2017-09-11
    • 2018-01-15
    相关资源
    最近更新 更多