#java #spring-boot #authentication #spring-security #bcrypt
#java #spring-boot #аутентификация #spring-безопасность #bcrypt
Вопрос:
Я пытался решить это с неделю и перепробовал все сообщения и все еще не мог получить эту работу. Мой класс SecurityConfiguration:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final DataSource dataSource;
@Value("${spring.queries.users-query}")
private String usersQuery;
@Value("${spring.queries.roles-query}")
private String rolesQuery;
public SecurityConfiguration(BCryptPasswordEncoder bCryptPasswordEncoder, DataSource dataSource) {
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.dataSource = dataSource;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.
jdbcAuthentication()
.passwordEncoder(bCryptPasswordEncoder)
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/","/h2-console/**","/registration","/login").permitAll()
.antMatchers("/offer/**").access("hasRole('USER') or hasRole('ADMIN')")
.and()
.formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/")
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied");
http.csrf().disable();
http.headers().frameOptions().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
}
}
и у меня есть класс WebMvcConfiguration следующим образом:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
}
Я просто продолжаю получать «Неверные учетные данные» и что пароль не соответствует записям. Я вижу хэшированный пароль в базе данных и настраиваю точку отладки непосредственно перед строкой, где класс DaoAuthenticationProvider выдает это исключение (метод additionalAuthenticationChecks), и, насколько я могу видеть, данные пользователя из базы данных поступают правильно, но он не показывает представленный пароль при входе в систему как закодированный…
Мой контроллер входа в систему выглядит следующим образом:
@Controller
public class LoginController {
private final UserAccountService userAccountService;
public LoginController(UserAccountService userAccountService) {
this.userAccountService = userAccountService;
}
@GetMapping("/login")
public ModelAndView login( Error error){
ModelAndView modelAndView = new ModelAndView();
if (error != null) {
modelAndView.setViewName("error page");
}
modelAndView.setViewName("login");
return modelAndView;
}
@PostMapping("/registration")
public ModelAndView createNewUser(@Valid UserAccount user, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
UserAccount userExists = userAccountService.findUserByEmail(user.getEmail());
if (userExists != null) {
bindingResult
.rejectValue("email", "error.user",
"There is already a user registered with the email provided");
}
if (bindingResult.hasErrors()) {
modelAndView.setViewName("registration");
} else {
userAccountService.saveOrUpdate(user);
modelAndView.addObject("successMessage", "User has been registered successfully");
modelAndView.addObject("user", new UserAccount());
modelAndView.setViewName("registration");
}
return modelAndView;
}
@GetMapping("/admin/home")
public ModelAndView home(){
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserAccount user = userAccountService.findUserByEmail(auth.getName());
modelAndView.addObject("userName", "Welcome " user.getFirstName() " "
user.getLastName() " (" user.getEmail() ")");
modelAndView.addObject("adminMessage","Content Available Only for Users with Admin Role");
modelAndView.setViewName("admin/home");
return modelAndView;
}
}
Мои SQL-запросы также работают корректно, я опробовал их на консоли H2…
как вы думаете, я делаю неправильно?
Комментарии:
1. $ 2a $ 10 $HwZisjNuFqVpiNeq399cKOUPZH8LVsKbQS4sniZeyewixc4a3eRP2 — это хэш, а 1234 — это то, что я ввожу при входе в систему..
Ответ №1:
Хорошо, я нашел виновника:
При запуске приложения я заполнял базу данных некоторыми тестовыми данными и понял, что обновлял учетные записи пользователей, в которых пароли были перекодированы…
Как только я сократил использование метода «saveOrUpdate» класса UserAccount, я смог войти в систему.