我正在尝试创建REST API。我可以创建帐户并登录,但当我尝试获取用户时,出现以下错误:java.lang.StackOverflowError: null
.
我知道这个问题涉及到递归方法调用,但我就是看不出它在哪里。
用户模型
@Entity
@Table(name = "TB_USER")
public class User implements Serializable, UserDetails {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "USER_ID", nullable = false)
private Long userId;
@Column(name = "COMPLETE_NAME", nullable = false, length = 60)
private String name;
@Column(name = "USERNAME", nullable = false, unique = true, length = 100)
private String username;
@Column(name = "PASSWORD", nullable = false, length = 200)
private String password;
// token e tokenCreationDate são usados para fins de recuperação de senha
@Column(name = "TOKEN")
private String token;
@Column(name = "CREATION_DATE_TOKEN")
private LocalDateTime tokenCreationDate;
public User() {
}
public User(Long userId, String name, String username, String password) {
this.userId = userId;
this.name = name;
this.username = username;
this.password = password;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.emptyList();
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public LocalDateTime getTokenCreationDate() {
return tokenCreationDate;
}
public void setTokenCreationDate(LocalDateTime tokenCreationDate) {
this.tokenCreationDate = tokenCreationDate;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return userId.equals(user.userId);
}
@Override
public int hashCode() {
return Objects.hash(userId);
}
}
用户存储库
第一个
用户控制器
@RestController
@RequestMapping("/user")
@CrossOrigin("*")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/all")
public ResponseEntity<List<User>> getAll() {
return ResponseEntity.ok(userService.findAll());
}
}
注册控制器
@RestController
@RequestMapping("/signup")
@CrossOrigin("*")
public class SignUpController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<?> signup(@RequestBody @Valid User user) {
HttpStatus status = userService.register(user);
if(status.equals(HttpStatus.BAD_REQUEST)) {
return ResponseEntity.badRequest()
.body("The password must include uppercase and lowercase letters numbers and symbols");
}
if(status.equals(HttpStatus.CONFLICT)) {
return ResponseEntity.status(HttpStatus.CONFLICT).body("Address already in use");
}
return ResponseEntity.status(HttpStatus.CREATED).body("Successful");
}
}
登录控制器
@RestController
@RequestMapping("/login")
@CrossOrigin("*")
public class LoginController {
@Autowired
private LoginService loginService;
@PostMapping
public ResponseEntity<UserLogin> authentication(@RequestBody UserLogin user) {
return ResponseEntity.ok(loginService.login(user));
}
}
登录服务
@Service
public class LoginService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder encoder;
public UserLogin login(@NotNull UserLogin user) {
Optional<User> u = userRepository.findByUsername(user.getUsername());
if(u.isEmpty() || !encoder.matches(user.getPassword(), u.get().getPassword())) {
throw new RuntimeException("Invalid credentials");
}
String auth = user.getUsername() + ":" + user.getPassword();
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));
String authHeader = "Basic " + new String(encodedAuth);
user.setToken(authHeader);
return user;
}
}
安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and()
.csrf().disable()
.authorizeHttpRequests((auth) -> auth
.antMatchers(HttpMethod.POST, "/login").permitAll()
.antMatchers(HttpMethod.POST, "/signup").permitAll()
.antMatchers(HttpMethod.POST, "/password/**").permitAll()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.anyRequest().authenticated()
)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.httpBasic();
return http.build();
}
}
最后...堆栈跟踪
ava.lang.StackOverflowError: null
at org.springframework.aop.framework.AdvisedSupport$MethodCacheKey.equals(AdvisedSupport.java:580) ~[spring-aop-5.3.23.jar:5.3.23]
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:940) ~[na:na]
at org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport.java:468) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:199) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy2/jdk.proxy2.$Proxy123.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
它会永远重复。
在一些教程之后,我尝试改变依赖关系,将一些端点放入同一个类中,并重构整个项目。
1条答案
按热度按时间xxe27gdn1#
我尝试删除SecurityConfig类中的bean authenticationManager。我遇到了同样的问题。现在我在Spring安全测试中得到了stackOverflowError