StackoverflowError on Login Request
Hi, i'm struggling
[Handler dispatch failed: java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null
310 Replies
⌛
This post has been reserved for your question.
Hey @Icca! Please useTIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here./close
or theClose Post
button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically marked as dormant after 300 minutes of inactivity.
SpringSecurityConfig.java :
@Configuration
public class SpringSecurityConfig {
@Value("${jwt.key}")
private String jwtKey;
@Bean
public UserDetailsService userDetailsService(CustomUserDetailsService customUserDetailsService) {
return customUserDetailsService;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/register", "/auth/login").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.build();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtDecoder jwtDecoder() {
SecretKeySpec secretKey = new SecretKeySpec(jwtKey.getBytes(), "HmacSHA256");
return NimbusJwtDecoder.withSecretKey(secretKey).macAlgorithm(MacAlgorithm.HS256).build();
}
@Bean
public JwtEncoder jwtEncoder() {
if (jwtKey == null || jwtKey.isEmpty()) {
throw new IllegalArgumentException("JWT KEY manquant");
}
SecretKeySpec secretKey = new SecretKeySpec(jwtKey.getBytes(), "HmacSHA256");
return new NimbusJwtEncoder(new ImmutableSecret<>(secretKey.getEncoded()));
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
CustomUserDetailsService.java : @Service
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Users user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("Utilisateur non trouvé : " + username));
return User.builder()
.username(user.getUsername())
.password(user.getPassword())
.authorities("USER")
.build();
}
}
UserService.java : @Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public UserViewModel saveUser(UserCreateModel userCreateModel, String email) {
String encodedPassword = passwordEncoder.encode(userCreateModel.getPassword());
Users newUser = new Users();
newUser.setUsername(userCreateModel.getUsername());
newUser.setPassword(encodedPassword);
newUser.setEmail(email);
Users savedUser = userRepository.save(newUser);
return new UserViewModel(savedUser.getId(), savedUser.getUsername(), savedUser.getEmail(), savedUser.getCreatedAt(), savedUser.getUpdatedAt());
}
}
UserController.java : @RestController
@RequestMapping("/auth")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JWTService jwtService;
public UserController(AuthenticationManager authenticationManager, JWTService jwtService) {
this.authenticationManager = authenticationManager;
this.jwtService = jwtService;
}
// Route pour l'enregistrement d'un nouvel utilisateur
@PostMapping("/register")
public UserViewModel register(@RequestBody UserCreateModel userCreateModel) {
// Récupérer l'email depuis le modèle de création ou en paramètre
String email = userCreateModel.getEmail(); // Ajout de l'email dans la requête
// Appeler le service pour enregistrer l'utilisateur
return userService.saveUser(userCreateModel, email);
}
// Route pour la connexion et la génération du token
@PostMapping("/login")
public String login(@RequestBody UserCreateModel loginRequest) {
try {
// Authentification de l'utilisateur
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()
)
);
// Générer un JWT après authentification réussie
return jwtService.generateToken(authentication);
} catch (AuthenticationException e) {
throw new RuntimeException("Nom d'utilisateur ou mot de passe incorrect", e);
}
}
}
Can you show the stack trace?
if something repeats a lot, you can truncate it but please still make it clear what's repeating
Also which request fails exactly?
at org.springframework.aop.support.AopUtils.isEqualsMethod(AopUtils.java:166) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:175) ~[spring-aop-6.2.0.jar:6.2.0]
at jdk.proxy2/jdk.proxy2.$Proxy124.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:216) ~[spring-aop-6.2.0.jar:6.2.0]
at jdk.proxy2/jdk.proxy2.$Proxy124.authenticate(Unknown Source) ~[na:na]
The POST onewhich one? /login? /register?
Im kinda beginner on Java sorry :3
/login* its on the title
is there not more to it?
There is a loooot more
can you truncate the repeating parts?
How do i truncate ? Im not that good at english :3
I still need at least one or two versions of the repeating part and the thing before and after
Do i have to give you an .txt of it ?
wazaaaaaaaap
I mean removing the duplicates
works as well
like normally you should have the same 5 lines or whatever over and over
Did you define your own
AuthenticationManager
?looks like generate token might be the problem
Also why are you using a mix between constructor autowiring and
@Autowired
?Im a full beginner XD
can you show the generate token method
yup
ok show then
public String generateToken(Authentication authentication) {
String username = authentication.getName();
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 24h
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
Can you show what's before that repeating part and what's after it?
or just paste the whole log in a file and post it here
And there is nothing after the repeating part
Like
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:216) ~[spring-aop-6.2.0.jar:6.2.0]
at jdk.proxy2/jdk.proxy2.$Proxy124.authenticate(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
yea the console doesnt print after that
That's the three last line
there should be something between
and
at least different lines starting with
at
ah no my fault
after it
at the endi did Ctrl A and paste it here
o mamma mia 110 kb
😱
So nothing wrong here ? @ayylmao123xdd
and the
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
is really the last line?yup
ok
yea seems to be ok
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
that's the last line i have on my consolewait
Did you define any
AuthenticationManager
anywhere?
Like your own implementation?@dan1st | Daniel look there
building username and setting username
that's not what I asked for
ye but isnt that the cause
I asked for the full concrete
AuthenticationManager
implemenetationi have this on my springsecurityConfig :
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
Can you check whether
CustomUserDetailsService#loadUserByUsername
is called before the exception?
using a debugger
that's exactly what I wanted to see
What's AuthenticationConfiguration
?i don't know AHAHAH
should i get rid of it ?
no
well you could try
can you try 2 different variables
because you have
But can you show me the exact class name of
AuthenticationConfiguration
?string username = .setsubject username
so in set subject for testing you can set subject to just ""
and check if it works
like that ?
ok so that's a Spring class - I see
Can you try commenting out that method completely?
and restarting the application
Does that change the result?
*/ to comment right ??
try that if daniels solution doesnt work
i do the whole class or just that
/*
at the beginning, */
at the end
just the things in that screenshotlik that ?
I meant the whole method
k
im restarting
i guess there is a problem there too
@Icca try this code i sent
ah, I see
and uncomment
Do you have any
AuthenticationProvider
bean?i don't think sooo, this could be in controllers or configuration ?
Ok, im doing it
probably configuration
nop
Do you have the Spring Tools plugin installed?
does it work
Can you show your
UserDetailService
?nop ):
y
still same error or what
stackoverflow
it's probably something similar to https://stackoverflow.com/a/75959980/10871900
Stack Overflow
Spring Boot authentication throws java.lang.StackOverflowError: null
I can successfully signup users. However, when it comes to logging in the following error is thrown. I couldn't solve this problem for days.
stacktrace
Servlet.service() for servlet [dispatcherServ...
yes
but you have
set subject (username)
cause he asked for that
in what i sent it was
so i ctrl Z
set subject ("")
after he asked
try to do it like that
(meaning the
CustomUserDetailService
class)i did
im doing it again
interesting
Can you check whether the
login
method is called?
e.g. using a debugger?what is E.g ? :3
It looks like
login
is called which calls authenticationManager.authenticate
which fails
Are you asking what a debugger is?It looks like you are having issues with debugging or issues that can be solved using a debugger.
Check out this article on dev.java to see how debugging works and how to use a debugger.
This Stack Overflow question and its answers also explain debugging in general.
These links describe how to use the debugger in some IDEs:
• Debugging in IntelliJ
• Debugging in Eclipse
no
he doesnt know what eg is
i didnt knew what e.g means :3
it means for example
it means for example
thanks
If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
copycat ezzzzzzzzzzzz
what did the logs show btw
which one
i have a debugger here
but nothing show
hmmmmmmm
@dan1st | Daniel any possibility authentication manager is calling itself all the time
ONLY FOR TESTING:
Can you try replacing that with
that's what I'm trying to find out the whole time
Bean btw
uppercase
fixed
yeah I wrote that in Discord
skibidi
im on mobile so cant see logs
the login method in your controller - do you know how a debugger works?
the logs are just
which is what happens when an
AuthenticationManager
and an AuthenticationProvider
fight for each otherim trying to fix the text
What's the error?
And are there quick fixes?
you might need to import
BadCredentialsException
from Spring SecurityFIXED HALF
getPassword()
That was an error when deleting too much
fixed all
im restarting the server now
niceeeee
I intentionally didn't make it
public
but that doesn't make a differenceOMG
btw you have Spring Tools 4 installed xd
Does it work?
Still 401 but YEAH WORKED
😱
yeah ): xd
ok so my implementation was just for testing
It isn't what you should actually use
oh ):
So your
AuthenticationManager
was the issueok so now you know what is the problem i guess
hmmm okk
If you press Ctrl+3, you should get a popup
enter "beans" there
there should be something like "Spring Beans view"
ehhhhh hold on
without the S :3
it should be "Spring Symbols"
yeah something green
then you should get something like that
like that i guess
yeah the view
.
in the search, enter
authenticationprovider
there is no provider
ok
Do you have any existing logic for validating the password etc?
how can i check ?
idk what you talking about )): im sorry
i only have encrypter
Did you write the code?
like here, on my JWTService.java
not at all
i started, but then i used AI sorry don't blame me ):
its really too hard
ok
but like, i can understand it like 70%
I have to understand it 100% in 1, 2 weeks ^_^
so essetially something needs to take the username/password and validate it
that's what happens here
an
AuthenticationManager
is typically responsible for handling the authenticationi have my Users.java entities
yeah the
AuthenticationManager
would contain the logic doing that stuffim using mysql
ohhh i see
i put that here just in case
Here, I wrote a prototypical one that should somewhat work
but you would probably want a proper implementation
yes i understand
instead of using
UserDetailService
, it could actually get the Users
instance or whatever from the DBok, but i need it to use
UserDetailService
right ?and perform all checks you would want
You don't have to
Oh !
I just used it because you already have it
normally you would have a bean class (
@Configuration
or @Service
) that implements AuthenticationManager
and implements the authenticate
method
my code is a shortcut that does that
you could put it in its own class
and you can decide what you want to do with it
alternatively you could change the login
method/endpoint to do that work and not use the AuthenticationManager
authenticationManager
is inside the class SpringSecurityConfig
which is a @Configuration classthe easiest one is the alternative one i guess
If you don't want an
AuthenticationManager
, you could also leave it as you had it before and define an AuthenticationProvider
I thinkDo i really need an
authenticationManager
?that one is a valid
AuthenticationManager
I think it's not strictly necessaryWhat if i keep your code ?
you could also let Spring create both of them and let it just use the information in the
UserDetailService
it shobut I am not entirely sure why Spring doesn't do that with your projectmight be my dependency too
Maybe it's related to the
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
Oh I think I found itDaoAuthenticationProvider (spring-security-docs 6.4.2 API)
declaration: package: org.springframework.security.authentication.dao, class: DaoAuthenticationProvider
this is the
AuthenticationProvider
using a UserDetailsService
I think you can also do
and use your old AuthenticationManager
or no AuthenticationManager
at allim trying like this
I think one of these options should work
Do you have an
AuthenticationManager
now?nop, and error occure my bad
then you could try with your previous
AuthenticationManager
that might work but I didn't test itso
with that, there is an error :
oh
that can be fixed
thanks
lets try
worked !
Now, postman time !
still 401 but everything else works
I meant that this one should work even without the custom
AuthenticationManager
if you want thatoh ok let me try to redo it so
at the end you can choose which one you want
Do you know how to use a debugger?
not really ): i just put the "print " thing ^^
Did you send a request to
/auth/login
there?yes !
ok with the last code
i have another error
Do you have any filter for JWT?
i do my request like that
ok yeah for now just use the
AuthenticationProvider
I told you aboutok so i get rid of
authenticationManager
my fault
I meant using the
AuthenticatioManager
I told you about which checks with UserDetailsService
and PasswordEncoder
and remove the AuthenticationProvider
(for now)ok
like that
still an error with postman
wait, don't put
jwtKey
hereyeah but it dosnt work ):
you can do
throw new BadCredentialsException("username or password wrong")
It looks like you are having issues with debugging or issues that can be solved using a debugger.
Check out this article on dev.java to see how debugging works and how to use a debugger.
This Stack Overflow question and its answers also explain debugging in general.
These links describe how to use the debugger in some IDEs:
• Debugging in IntelliJ
• Debugging in Eclipse
oh ok !
nice !
That one shows you how to use a debugger
thanks ! i'll keep tthat in mind
I really recommend reading that
(Disclaimer: I wrote the dev.java article)
D:
So I would like you to debug the authentication provider
Damnnn im not talking to a random XD
Ok !
SHould i do it now ?
Set a breakpoint in the
UserDetails userDetails = ...
line
by double-clicking to the left of that lineshould look like that
eh no don't collapse it
that's the wrong icon
oh aha
wait im trying again XD
Oh !!
Yeah i see ! a breakpoint !
perfect
niiceee
now run the application in debug mode
meaning you start it with this icon
i did it
now
I wanted a good resource to explain debugging - Because I have to constantly explain it
i do my request on postman ?
yes
ahaha understandable
oh, its loading
indefinetly
check Eclipse
switch
and you should get a green line
Eclipse stopped (suspended) the application at the green line - this should be at your breakpoint
yes
Can you reset the debug perspective like this?
right click on the debug icon on the top right and click reset
not there
on the right
i did
yup, found it
perfect
so on the right, you see your current variables and their values
yes !
auth, with the value
Can you expand
auth
there?Note: You are in the application, the application waits for you
you see your username and password there
yes !!
Now press F6 once
OMG that is beautiful i have no idea wtf is going on
OK
the green line should move down
huuh, i saw some animations
yes
this means Eclipse executed line 79
oh !! ok !
and now it's waiting at line 80
OH YES
i see the arrow
you can expand the
userDetails
in the variables viewDo you see the capabilities of using a debugger?
That is insaaaaneee
Now I'll show you more
Bro i keep being amazed xD
so you would maybe like to see the result of the
passwordEncoder.matches()
method, maybe even before it's executed?yes
withtout even moving the green line u mean
now copy the
passwordEncoder.matches(...)
i guess
then go to the "Expressions" view
!passwordEncoder.matches(String.valueOf(auth.getPrincipal()), userDetails.getPassword()))
add "Add new expression"
and paste it there
then I think that's one
)
too muchok done it without the
)
then Eclipse should try to evaluate it and get a result
so it mean that its work
FOUND IT ! Everything working well !
i used Dao so spring could automaticly work with the authentification, AND with the password/encryptage. When using
AuthenticationConfiguration
its easier to manage the Auth.Thanks a lot for your help, i'll remember you as my hero ✅ 🙂
If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
Post Closed
This post has been closed by <@641713741355941917>.