Стоит задача - сделать самую базовую аутентификацию, просто через post запросы, без окон, без валидации, без всего.
Пароли надо хешировать bcrypt, и хранить пользователей в БД, роли не нужны.
Абсолютно все гайды предлагают какие-то очень сложные системы, через которых нереально пробираться в поисках того, что надо. И так, что у меня есть на данный момент:
User.java
@Getter
@Setter
@Entity
@Table(name = "users")
@Transactional
@NoArgsConstructor
public class User {
@Id
@GeneratedValue( strategy =
GenerationType.AUTO)
private Long id;
@Column(name = "username")
private String username;
@Column(name = "hashpass")
private String hashPass;
public User(String username, String hashPass) {
this.username = username;
this.hashPass = hashPass;
}
}
UserRepo.java
@Repository
public interface UserRepo extends CrudRepository<User, Long> {
@Query(value = "select * from users where username = ?1", nativeQuery = true)
User findUserByUsername(String username);
}
UserController.java
@RestController
public class UserController {
@Autowired
UserRepo userRepo;
@Autowired
SecurityService securityService;
@PostMapping("/register")
public String register(@RequestParam(value = "username", defaultValue = "null") String username, @RequestParam(value = "password", defaultValue = "null") String password){
if(username.equals("null") || password.equals("null")){
return null;
}
userRepo.save(new User(username, password));
securityService.autoLogin(username, password);
return "redirect:/home";
}
}
SecurityServiceImpl.java
@Service
public class SecurityServiceImpl implements SecurityService{
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Override
public String findLoggedInUsername() {
Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails();
if(userDetails instanceof UserDetails){
return (((UserDetails) userDetails).getUsername());
}
return "Error";
}
@Override
public void autoLogin(String username, String password) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, password, List.of(new SimpleGrantedAuthority("ROLE_USER")));
authenticationManager.authenticate(authenticationToken);
if (authenticationToken.isAuthenticated()){
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
}
UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService{
@Autowired
UserRepo userRepo;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public void save(User user) {
user.setHashPass(bCryptPasswordEncoder.encode(user.getHashPass()));
}
@Override
public User findByUsername(String username) {
return userRepo.findUserByUsername(username);
}
}
SecurityConfig.java
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().disable()
.authorizeRequests()
.antMatchers("/login", "/logout", "/register").permitAll()
.anyRequest().authenticated()
.and().formLogin()
.and().userDetailsService(userDetailsService());
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
}
С БД точно проблем никаких нет, с ней разобраться легко. А вот как дальше всё это соединять непонятно. В текущей вариации сервер запускается, но ничего не работает. Возможно, для моей задачи некоторые классы и не нужны.