Требуется помощь Spring SecurityJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Требуется помощь Spring Security

Сообщение Anonymous »

Я новичок в Spring Boot и особенно в Spring Security. Я создаю серверную часть проекта и не могу разобраться в концепции безопасности. Я знаю, что он делает и что мне действительно нужно.
До безопасности я построил все, что есть (для пользователей):

Контроллер:

Код: Выделить всё

package de.ExpenseTracker.controller;

import de.ExpenseTracker.dto.RegisterUserData;
import de.ExpenseTracker.dto.ResponseData;
import de.ExpenseTracker.dto.LoginUserData;
import de.ExpenseTracker.service.UserService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Locale;

@RestController
@RequestMapping("/users")
@AllArgsConstructor
public class UserController {
private final UserService userService;
private final MessageSource messageSource;

/**
* Registers a new user
*
* @param registerUserData DTO containing username, password and password confirmation
* @return ResponseData with username and message key
*/
@PostMapping("/register")
public ResponseData register(@Valid @RequestBody RegisterUserData registerUserData) {
userService.register(registerUserData);

return ResponseData.builder()
.messageKey(messageSource.getMessage("USER.CREATED", null, getLocale()))
.username(registerUserData.getUsername())
.build();
}

/**
* Logs in an existing user
*
* @param loginUserData DTO containing username and password
* @return ResponseData with message key
*/
@PostMapping("/login")
public ResponseData login(@Valid @RequestBody LoginUserData loginUserData) {
userService.login(loginUserData);

return ResponseData.builder()
.messageKey(messageSource.getMessage("USER.LOGGED_IN", null,  getLocale()))
.build();
}

private Locale getLocale() {
return LocaleContextHolder.getLocale();
}
}
Сервисный уровень:

Код: Выделить всё

package de.ExpenseTracker.service;

import de.ExpenseTracker.dto.LoginUserData;
import de.ExpenseTracker.dto.RegisterUserData;
import de.ExpenseTracker.exceptions.ErrorCode;
import de.ExpenseTracker.exceptions.InvalidCredentialsException;
import de.ExpenseTracker.exceptions.UserNotFoundException;
import de.ExpenseTracker.model.Users;
import de.ExpenseTracker.repository.UserRepository;
import de.ExpenseTracker.exceptions.UserAlreadyExistsException;
import lombok.AllArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.UUID;

@Service
@AllArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;

/**
* Registers a new User
*
* @param registerUserData the DTO that is given with user credentials
* @return The created Users entity
* @throws UserAlreadyExistsException  if the username with the given username already exists
* @throws InvalidCredentialsException if the password and confirmation do not match
*
*/
public Users register(RegisterUserData registerUserData) throws UserAlreadyExistsException {
if (checkUserExist(registerUserData.getUsername())) {
throw new UserAlreadyExistsException(ErrorCode.USER_EXISTS);
}

if (!registerUserData.getPassword().equals(registerUserData.getPasswordConfirm())) {
throw new InvalidCredentialsException(ErrorCode.PASSWORD_MISMATCH);
}

Users user = Users.builder()
.userid(UUID.randomUUID())
.username(registerUserData.getUsername())
.passwordHash(passwordEncoder.encode(registerUserData.getPassword()))
.createdAt(Instant.now())
.build();

return userRepository.save(user);
}

/**
* Checks user Credentials for login and updates it if login is successful
*
* @param userData DTO containing username and password
* @return true if login is successful
* @throws UserNotFoundException       if the username does not exist
* @throws InvalidCredentialsException if the password is incorrect
*/
public boolean login(LoginUserData userData) {
Users user = userRepository.findByUsername(userData.getUsername())
.orElseThrow(() -> new UserNotFoundException(ErrorCode.USER_NOT_FOUND));

boolean valid = passwordEncoder.matches(userData.getPassword(), user.getPasswordHash());

if (!valid) {
throw new InvalidCredentialsException(ErrorCode.PASSWORD_INCORRECT);
}

user.setLastLogin(Instant.now());

userRepository.save(user);

return true;
}

/**
* Retrieves a User entity from the database by its UUID
*
* @param userId The ID of the user to fetch
* @return the User entity
* @throws UserNotFoundException if no user with the given ID is found
*/
public Users getUserByIdOrThrow(UUID userId) {
return userRepository.findById(userId)
.orElseThrow(() ->  new UserNotFoundException(ErrorCode.USER_NOT_FOUND));
}

private boolean checkUserExist(String username) {
return userRepository.existsByUsername(username);
}
}
и моя базовая конфигурация безопасности:

Код: Выделить всё

package de.ExpenseTracker.config.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/users/register").authenticated()
.anyRequest().permitAll());
return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Я просто не могу понять: какой из всех классов аутентификации мне действительно нужен, и (насколько я правильно прочитал) я бы добавил .loginForm() в конфигурацию безопасности, и браузер сделал бы запрос на получение для этого, что сделало бы мой LoginController бесполезным, но я все равно хочу обновить свой последний вход от пользователя.
Я надеюсь, что вопрос не слишком широк. написано.

Если вы предоставите хорошие ресурсы, где я смогу посмотреть, как это работает, это будет здорово.

Заранее спасибо!

Подробнее здесь: https://stackoverflow.com/questions/798 ... elp-needed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»