У меня проблема с Spring Security. Когда я пытаюсь аутентифицировать пользователя в своем приложении, меня перенаправляют обратно на Signin.html. После отладки я увидел, что даже если я создаю экземпляр SecurityContextHolder.getContext().setAuthentication(); , SecurityContext имеет значение null.
Это мой код аутентификации:
public boolean dbAuthentication(String username, String password) {
Boolean response = false;
try {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
response = passwordEncoder.matches(password, userDetails.getPassword());
if (response) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
if (usernamePasswordAuthenticationToken.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
} catch(Exception e) {
response = false;
}
return response;
}
Это мой класс WebSecurityConfig:
public class WebSecurityConfig {
@Autowired
private AppConfig appConfig;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() throws Exception{
return (web) -> web.ignoring().requestMatchers( "/build/**","/ext/**","/resources/**","../../../resources/**","/../../resources/**","../resources/**");
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.
csrf(AbstractHttpConfigurer::disable).
headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin))
.authorizeHttpRequests(a -> a
.requestMatchers("/app/**").permitAll()
.requestMatchers("/signin.html").permitAll()
.requestMatchers("/forgot.html").permitAll()
.requestMatchers("/getCustomCss/**").permitAll()
.requestMatchers("/oauth2sso/**").permitAll()
.requestMatchers("/isLdapEnabled/**").permitAll()
.requestMatchers("/isSamlEnabled/**").permitAll()
.requestMatchers("/prefetchFiles*").permitAll()
.requestMatchers("/languages/getLanguages*").permitAll()
.requestMatchers("/getSessionTimeout").permitAll()
.requestMatchers("/wakeUpElastic/**").permitAll()
.requestMatchers("/forgotPassword*").permitAll()
.requestMatchers("/recoverPassword*").permitAll()
.requestMatchers("/authenticate*").permitAll()
.requestMatchers("/build/**").permitAll()
.requestMatchers("/ext/**").permitAll()
.requestMatchers("/resources/**").permitAll()
.requestMatchers("/logout*").permitAll()
.anyRequest().authenticated()
).formLogin(formLogin -> formLogin.loginPage("/signin.html").
usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/index.html", true)
.failureUrl("/signin.html?error=true"))
.logout(l -> l
.invalidateHttpSession(true)
.deleteCookies("SESSIONID")
.logoutUrl("/signin.html?logout"));
return http.build();
}
}
Эта проблема возникает, когда я пытаюсь обновить версию SpringSecurity до последней версии и пытаюсь следовать всем инструкциям из официальной документации, но безуспешно.
Я думаю, вы имеете в виду эту строку в методе dbAuthentication(..), поскольку вы создали экземпляр SecurityContext.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
Проблема в том, что вы получаете SecurityContext от SecurityContextHolder и пытаетесь установить значение аутентификации, что не рекомендуется. Вам необходимо заполнить контекст безопасности как
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication =
new TestingAuthenticationToken("username", "password", "ROLE_USER");
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
Только тогда вы сможете его использовать.
Что касается невозможности найти его в документации, вот ссылка на официальный документ по настройке SecurityContext.