@postya

Как перенаправить пользователя на его страницу если он снова хочет залогиниться в Spring Boot?

Пишу веб приложение. Использую Spring Boot, Spring Security, Thymeleaf.

На главном экране есть кнопка Login. При клике на неё пользователь направляется на экран логина. После того,как пользователь залогинился он перенаправляется на свою страницу: `http://localhost:8080/user/home`

Как сделать так,чтобы если пользователь, после того как авторизовался и снова нажал на кнопку Login на главном экране он направлялся прямиком на свою страницу, а не на экран с логином?

По нажатию на кнопку Login thymeleaf делает Get запрос
<div class="doctor-button">
         <a class="button-click doctor-button" th:href="@{/login}">LOGIN</a>
 </div>


а в контроллере этот get запрос делает следующее:

@GetMapping("/login")
  public ModelAndView login() {
    ModelAndView modelLogin = new ModelAndView();  
    modelLogin.setViewName("login");
     return modelLogin;  
}


я пробовал изменить этот запрос на это, но ничего не помогло:

@GetMapping("/login")
  public ModelAndView login(HttpServletRequest httpServletRequest, Model model) {
    ModelAndView modelLogin = new ModelAndView();
    ModelAndView modelAdminHome = new ModelAndView();
    ModelAndView modelUserHome = new ModelAndView();
    ModelAndView modelDoctorHome = new ModelAndView();

    modelLogin.setViewName("login");
    modelAdminHome.setViewName("admin/home");
    modelUserHome.setViewName("user/home");
    modelDoctorHome.setViewName("doctor/home");

    if (httpServletRequest.isUserInRole("ADMIN")) {
      return modelAdminHome;
    }
    else if(httpServletRequest.isUserInRole("DOCTOR")) {
      return modelDoctorHome;

    } else if (httpServletRequest.isUserInRole("USER")) {
      return modelUserHome;

    } else {

    }

    return modelLogin;

  }


Может в thymeleaf есть какая-то функция для этого?

WebMvcConfig:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

  @Bean
  public BCryptPasswordEncoder passwordEncoder() {
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    return passwordEncoder;
  }

}


SecurityConfiguration:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private AuthenticationSuccessHandler successHandler;

  @Autowired
  private BCryptPasswordEncoder passwordEncoder;

  @Autowired
  private DataSource dataSource;

  @Value("${spring.queries.users-query}")
  private String usersQuery;

  @Value("${spring.queries.roles-query}")
  private String rolesQuery;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.jdbcAuthentication()
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource)
            .passwordEncoder(passwordEncoder);
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/", "/about", "/services", "/login", "/register", "/doctors", "/billings", "/signup").permitAll()
            .antMatchers("/admin/**").hasAnyAuthority("ADMIN")
            .antMatchers("/user/**").hasAnyAuthority( "USER", "ADMIN")
            .antMatchers("/doctor/**").hasAnyAuthority( "DOCTOR", "ADMIN")
            .anyRequest().authenticated()
            .and()
            // form login
            .csrf().disable().formLogin()
            .loginPage("/login")
            .failureUrl("/login?error=true")
            .successHandler(successHandler)
            .usernameParameter("email")
            .passwordParameter("password")
            .and()
            // logout
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/").and()
            .exceptionHandling()
            .accessDeniedPage("/access-denied");
  }

  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring()
            .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**", "/fonts/**");
  }
}


CustomAuthenticationSuccessHandler:

@Configuration
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

  
  @Override
  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());

    if (roles.contains("ADMIN")) {
      response.sendRedirect("/admin/home");
    } else if (roles.contains("DOCTOR")) {
      response.sendRedirect("/doctor/home");
    }
    else {
      response.sendRedirect("/user/home");
    }
  }
}
  • Вопрос задан
  • 2282 просмотра
Решения вопроса 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Здравствуйте!
Все довольно просто.
1) можно показывать кнопку login только неавторизованным пользователям.
В thymeleaf подключите spring security thymeleaf extras, а дальше проверяйте по
https://www.thymeleaf.org/doc/articles/springsecur... (Глава 4)
<div sec:authorize="isAnonymous()">
<!-- login button here for non logged-in users -->
</div>


Но если вы все же хотите показывать кнопку и редиректить пользователя в его личный кабиент по нажатию кнопки login, в случае, если он уже авторизован, то:

В методе, который возвращает /login (в контроллере) сделайте проверку:

if(
        SecurityContextHolder.getContext().getAuthentication() != null &&
        SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
        !(SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken)

    ) {

      return "redirect:/home";
    }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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