I want to create a username and login in my project. I can create username but, I cannot login to the system with the username I created.
I'm trying to login in my application with spring security, but it gives me an error. Also, I'm storing my password in data base in bcrypted form. In associate table I have got userid and roleid. But I can't login. What I've missed? User table in mysql
I couldn't solve this problem, can you help me please?
Default;
username=admin
password=admin
Here is my User Repository
public interface IUserRepository extends JpaRepository<User, Long> {
Optional<User> findUserByUsername(String username);
Here is my USER SERVİCE
Optional<User> findUserByUsername(String username);
void save(User user);
void autoLogin(HttpServletRequest request, String username, String password);
Here is my UserserviceImpl
public class UserServiceImpl implements IUserService {
@Autowired
private IUserRepository iuserRepository;
@Autowired
private IRoleRepository iRoleRepository;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public Optional<User> findUserByUsername(String username) {
return iuserRepository.findUserByUsername(username);
}
@Override
public void save(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
user.setActive(true);
Role userRole = iRoleRepository.findRoleByName("ROLE_USER");
user.setRoles(new HashSet<>(Arrays.asList(userRole)));
iuserRepository.save(user);
}
@Override
public void autoLogin(HttpServletRequest request, String username, String password) {
UsernamePasswordAuthenticationToken authToken = new
UsernamePasswordAuthenticationToken(username, password);
authToken.setDetails(new WebAuthenticationDetails(request));
Authentication authentication = authenticationManager.authenticate(authToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
Here is my Login Page
<form th:action="@{/login}" method="post">
<div >
<label >Username</label>
<input type="text" id="username" required placeholder="Enter Username">
</div>
<div >
<label>Password</label>
<input type="password" id="password" required placeholder="Password">
</div>
<button type="submit" >Submit</button>
</form>
</div>
Here is my Controller public class UserRegistrationController {
@Autowired
private IUserService iUserService;
@Autowired
private IAnimalOwnersService iAnimalOwnersService;
@Autowired
private IAnimalsService iAnimalsService;
@ModelAttribute("user")
public User user() {
return new User();
}
@GetMapping("/")
public String indexPage() {
return "index";
}
@GetMapping("/index")
public String indexPage2() {
return "index";
}
@GetMapping("/register")
public String registerShowPage() {
return "register";
}
@PostMapping("/register")
public String registerPage(@Valid @ModelAttribute("user") User user, BindingResult bindingResult, Model theModel, HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
return "register";
}
String username = user.getUsername();
String password = user.getPassword();
Optional<User> optionalUser = (iUserService.findUserByUsername(username));
if (optionalUser.isPresent()) {
theModel.addAttribute("alreadyExistsUser", "Username is used");
return "register";
}
iUserService.save(user);
iUserService.autoLogin(httpServletRequest, username, password);
List<String> userRoleNames =
user.getRoles().stream().map(Role::getName).collect(Collectors.toList());
redirectAttributes.addFlashAttribute("username", username);
return "redirect:/index";
}
@GetMapping("/dashboard")
public String dashboardPage(Model theModel) {
Long totalOwners = iAnimalOwnersService.totalUsers();
Long totanAnimals = iAnimalsService.totalAnimals();
theModel.addAttribute("totalOwners", totalOwners);
theModel.addAttribute("totanAnimals", totanAnimals);
return "dashboard";
}
@GetMapping({"/login", "/login.html"})
public String loginPage() {
return "login";
}
Here is my Configuration
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
private final String USERS_QUERY = "select username, password, active from user where username=?";
private final String ROLES_QUERY = "select u.username, r.name from user u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.username=?";
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.usersByUsernameQuery(USERS_QUERY)
.authoritiesByUsernameQuery(ROLES_QUERY)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers()
.permitAll()
.antMatchers("/register", "/login", "/index", "/")
.permitAll();
http.authorizeRequests().antMatchers("/actuator/**").hasRole("ADMIN");
http.authorizeRequests().anyRequest().authenticated();
http
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.failureUrl("/login?loginFailed=true")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/dashboard.html", true)
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/index");
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
CodePudding user response:
I fixed the error, thank you. @Toerktumlar @Roar S.
Adding a name to the form was enough.
<div >
<label >Username</label>
<input type="text" name="username" id="username" required placeholder="Enter Username">
</div>
<div >
<label>Password</label>
<input type="password" name="password" id="password" required placeholder="Password">
</div>
<button type="submit" >Submit</button>