P
P
postya2019-05-25 18:20:34
Java
postya, 2019-05-25 18:20:34

How to redirect the user to his page if he wants to login to Spring Boot again?

I am writing a web application. I use Spring Boot, Spring Security, Thymeleaf.
There is a Login button on the main screen. Clicking on it takes the user to the login screen. After the user is logged in, he is redirected to his page: ` http://localhost:8080/user/
home` your page, and not on the login screen?
On clicking the Login button thymeleaf makes a Get request

<div class="doctor-button">
         <a class="button-click doctor-button" th:href="@{/login}">LOGIN</a>
 </div>

and in the controller this get request does the following:
@GetMapping("/login")
  public ModelAndView login() {
    ModelAndView modelLogin = new ModelAndView();  
    modelLogin.setViewName("login");
     return modelLogin;  
}

I tried changing this query to this, but nothing helped:
@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;

  }

Is there a function in thymeleaf for this?
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");
    }
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Orkhan, 2019-05-25
@postya

Hello!
Everything is pretty simple.
1) you can show the login button only to unauthorized users.
In thymeleaf, enable spring security thymeleaf extras, and then check against
https://www.thymeleaf.org/doc/articles/springsecur... (Chapter 4)

<div sec:authorize="isAnonymous()">
<!-- login button here for non logged-in users -->
</div>

But if you still want to show the button and redirect the user to his personal account by pressing the login button, in case he is already authorized, then:
In the method that returns /login (in the controller), check:
if(
        SecurityContextHolder.getContext().getAuthentication() != null &&
        SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
        !(SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken)

    ) {

      return "redirect:/home";
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question