@My1Name

Spring Security: Как получить username и password?

На странице /login.jsp есть форма:
<c:url value="/perform_login" var="login" />
    <form action="${login}" method="post">
        <h2 class="form-signin-heading">Please sign in</h2>
        <input type="text" class="form-control" name="username">
        <input type="password" class="form-control" name="password">
        <button class="btn btn-lg btn-primary btn-block" type="submit">Войти</button>
    </form>

При входе на сайт выполняется проверка (аутентификация) следующим образом:
HttpSecurity http
.........
http.formLogin()
	        .loginPage("/login")
	        .loginProcessingUrl("/perform_login")
	        .failureUrl("/login.html?error=true")

Я пытаюсь получить username и password в контроллере:
@RequestMapping (method = RequestMethod.POST)
	public void logInForm(@RequestParam(value="username") String login, 
						  @RequestParam(value="password") String password, Model model) {
		System.out.println("aaaaaaaaaaa");
	
	}

но спринг почему-то обходит контроллер стороной (не видит его, и перенаправляет на главную страницу приложения в случае удачной аутентификации)... Если заменить строки на странице /login.jsp
<c:url value="/perform_login" var="login" /> 
<form action="${login}" method="post">

одной строкой <form action="login" method="post"> то тогда контроллер становится видимым. Как получить username и password?
  • Вопрос задан
  • 262 просмотра
Решения вопроса 1
@My1Name Автор вопроса
В Spring Security нельзя получить username и password привычными методами. После аутентификации запроса, данные обычно хранятся в локальном потоке SecurityContext, управляемом SecurityContextHolder. А чтоб достать username и password, нужно переопределить метод "Authentication" в классе AuthenticationProvider ("прослойка" между базой данных и клиентом, вшитая в Spring Security):
@Component
public class CustomAuthencationProvider implements AuthenticationProvider {
    @Autowired
    private CustomPersonRepository DAO;
    @Override
    public Authentication authenticate(Authentication authentication) 
                                          throws AuthenticationException {
        String userName = authentication.getName();
        String password = authentication.getCredentials().toString();
        Person myUser = DAO.findByUsername(userName);
        if (myUser == null) {
            throw new BadCredentialsException("Unknown user "+userName);
        }
        if (!password.equals(myUser.getPassword())) {
            throw new BadCredentialsException("Bad password");
        }
        UserDetails principal = User.builder()
                .username(myUser.getLogin())
                .password(myUser.getPassword())
                .roles(myUser.getLogin())
                .build();
        return new UsernamePasswordAuthenticationToken(
                principal, password, principal.getAuthorities());
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Спринг работает на прямую с объектами "User" хранящимися в базе данных (или в локальном репозитории) и автоматизирует процесс обмена данными до уровня "запрос - ответ", а в контексте происходит аутентификация (кодирование/декодирование + проверка). То есть, хождение по сайту, подразумевает постоянный обмен пакетами данных сервера и клиента, между которыми существует прослойка "проверка" (аутентификация) реализованная в Spring Security. И если нам нужно что-то достать, то нужно реализовать методы спринга. В идеале, даже разработчик не должен видеть личные данные пользователя.

Пароль в Spring Security по умолчанию закодирован на уровне контекста. И если мы хотим убрать кодирование (не рекомендуется), то нужно в классе конфигурации SecurityConfig implements WebMvcConfigurer указать соответствующий бин:
@Bean
	 public PasswordEncoder passwordEncoder() {
		return NoOpPasswordEncoder.getInstance();
	 }

Пользовательская аутентификация в Spring Security
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@gerashenko
@PostMapping("/login")?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы