Настройка функции запоминания меня в Spring Security

#java #spring #spring-mvc #spring-security

#java #spring #spring-mvc #spring-безопасность

Вопрос:

Rememberconfigurer использует UserDetailsService, вызывая свой метод loadUserByUsername(), проблема в том, что я хочу, чтобы он передавал адрес электронной почты пользователя, а не имя пользователя. Он работает с простым входом в систему, но не с опцией запомнить меня. Как я могу заставить функцию запоминания меня передавать электронную почту (не имя пользователя) в UserDetailsService.loadUserByUsername()? форма входа:

 <form action="login" method="POST" >

              <legend>Sing In</legend>

              <div class="form-group">

                <div class="input-group">
                  <label class="form-label" for="email">
                    Email
                  </label>

                  <div class="form-input-field">

                      <input id="email" name="username"
                             type="text" autocomplete="off"/>
                  </div>
                </div>

              </div>

              <div class="form-group">

                <div class="input-group">
                  <label class="form-label" for="password">
                    Password
                  </label>

                  <div class="form-input-field">

                      <input id="password" name="password"
                             type="password" autocomplete="off" />
                  </div>
                </div>

              </div>

              <div class="form-group">

              <div class="input-group">
                <label id="checkbox-label" class="form-label" for="remember">
                  Remember me
                </label>

                <div class="form-input-field">

                    <input id="remember" name="remember"
                           type="checkbox" />
                </div>

              </div>

              <div id="submit-button">

                  <input type="submit" value="Sign In" />

              </div>

      </form>
 

Настройка WebSecurityConfiguration:

 @Override
    public void configure(HttpSecurity httpSecurity) throws Exception {

        httpSecurity.formLogin()
                        .loginPage("/login")
                        .permitAll()
                        .defaultSuccessUrl("/account")
                    .and()
                        .rememberMe()
                        .key("rem-me-key")
                        .userDetailsService(userDetailsService)
                        .rememberMeParameter("remember")
                        .rememberMeCookieName("rememberMeCookie")
                        .tokenValiditySeconds(60 * 60 * 24 * 3)
                    .and()
                        .logout()
                        .deleteCookies("JSESSIONID")
                        .permitAll();

        httpSecurity.authorizeRequests()
                    .mvcMatchers("/admin").hasRole("ADMIN")
                    .mvcMatchers("/account").hasRole("CUSTOMER")
                    .mvcMatchers("/cart").hasRole("CUSTOMER")
                    .anyRequest().permitAll();


        httpSecurity.csrf()
                    .disable();

    }
 

UserDetailsService impl:

 @Service
public class AppUserDetailsService implements UserDetailsService {

    private static final Logger log =
            LogManager.getLogger(AppUserDetailsService.class.getName());

    private AppUserRetrievalRepository appUserRetrievalRepository;

    public AppUserDetailsService(
            @Autowired
            AppUserRetrievalRepository appUserRetrievalRepository) {

        this.appUserRetrievalRepository = appUserRetrievalRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String email)
            throws UsernameNotFoundException {

        log.info("Trying to load user by name: "   email);

        Optional<AppUser> optUser =
                appUserRetrievalRepository.getUserByEmail(email);

        UserDetails userDetails =
                new AppUserDetails(optUser.orElseThrow(
                        () -> new UsernameNotFoundException(email   " cannot be found") )
                );

        return userDetails;
    }
}
 

Журналы, показывающие проблему:
~ Когда я использую логин без отмеченной опции запомнить меня:

 *** LOG4J *** Trying to load user by name: myEmailAddress@example.com
 

~ Когда я использую логин с проверенной опцией запомнить меня:

 *** LOG4J *** Trying to load user by name: cody
 

Комментарии:

1. I want it to pass user's email and not username. It works with simple login, but not with remember me option. Я не понимаю вашего вопроса. Пожалуйста, напишите более подробно, с журналами отладки, которые показывают проблему.

2. Таким образом, адрес электронной почты является именем пользователя, и ваша UserDetails реализация должна отражать это.

3. Я так и сделал. Если я правильно понял, проблема в том, что после успешной аутентификации RememberMeConfigurer использует метод loadByUsername() для получения пользователя и создания файла cookie. Было бы хорошо, если бы он передавал электронную почту (myEmailAddress@example.com ), но он передает имя пользователя (cody).

4. Потому что, я полагаю, что ваш AppUserDetails не возвращает адрес электронной почты должным образом в качестве имени пользователя, которое оно должно.

5. Да, это сработало. Спасибо, М. Дейнум!