Spring Boot Redirect на запрошенный URL после входа в систему - PullRequest
0 голосов
/ 07 июня 2018

У меня есть приложение Spring Boot UI.Я пытаюсь перенаправить пользователей на первоначально запрошенный URL-адрес после входа в систему.

Когда пользователь запрашивает http://www.example.com/myapp/user/22,, приложение удачно перенаправляет на http://www.example.com/myapp/login. После входа пользователя приложение перенаправляетна http://www.example.com/myapp/dashboard. Я бы хотел, чтобы приложение перенаправляло на http://www.example.com/myapp/user/22.

Я просмотрел несколько ссылок и чувствую, что у меня правильная конфигурация, но перенаправление работает не так, как ожидалось.

Моя настройка безопасности

public class SecurityConfig extends WebSecurityConfigurerAdapter {
.....
....

    @Autowired
    private MyAuthenticationSuccessHandler authenticationSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
        authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .and().csrf().disable().formLogin()
                .successHandler(authenticationSuccessHandler)
......

, а мой обработчик успеха -

    @Component
    public class MyAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    ...
public MyAuthenticationSuccessHandler() {
        super();
        this.setDefaultTargetUrl("/myapp/dashboard");
        this.setUseReferer(true);
    }

        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                Authentication authentication) throws IOException, ServletException {
            //Do something ..........
            ........
            .........
            super.onAuthenticationSuccess(request, response, authentication);
}

Я тоже пытался использовать SavedRequestAwareAuthenticationSuccessHandler.

Я заметил, что мой обработчик успеха вызывается, но целевым URL-адресом всегда является / user / login, и вызывается мой контроллер входа в систему ..

@RequestMapping("/login")
public ModelAndView login(@ModelAttribute() {
    if(!userIdentified) {
        //go to login page
    } else {
        new ModelAndView("redirect:/myapp/dashboard");
    }
}

и пользователь перенаправляется на «панель управления».

Что еще мне не хватает?

Ответы [ 3 ]

0 голосов
/ 27 апреля 2019

Хотя Singgih S ответ работает, НО есть лучший способ, как показано ниже: Ref: https://www.baeldung.com/spring-security-redirect-login

В этих магиях нетпростые в использовании функции в Spring Security.Когда запрашивается защищенный ресурс, запрос будет отфильтрован цепочкой различных фильтров.Принципы аутентификации и разрешения будут проверены.Если сеанс запроса еще не аутентифицирован, будет выдано AuthenticationException.

AuthenticationException будет перехвачено в ExceptionTranslationFilter, в котором будет начат процесс аутентификации, что приведет к перенаправлению на страницу входа.

Следовательно:
1. Когда происходит перенаправление на страницу "/ login", ваш защищенный URL-адрес запроса сохраняется в сеансе как DefaultSavedRequest объект.
2.Также мы знаем, что при успешном входе в систему на основе форм вызывается одна из реализаций AuthenticationSuccessHandler.поэтому мы можем создать собственный класс и получить DefaultSavedRequest в нем, как показано ниже:

public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        DefaultSavedRequest defaultSavedRequest = (DefaultSavedRequest) request.getSession().getAttribute("SPRING_SECURITY_SAVED_REQUEST");
        if(defaultSavedRequest != null){
            getRedirectStrategy().sendRedirect(request, response, defaultSavedRequest.getRedirectUrl());
        }else{
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }
}


3. Мы должны представить этот класс в WebSecurityConfigurerAdapter:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.(...).anyRequest().authenticated().and()
                        .formLogin()
                        .loginPage("/login")
                        .loginProcessingUrl("/login")
                        .successHandler(new CustomAuthenticationSuccessHandler());

Таким образом, вы можете реализовать свою логику в вышеуказанном методе onAuthenticationSuccess.
С наилучшими пожеланиями

0 голосов
/ 16 июня 2019

Маршрут Spring, расширяющий SavedRequestAwareAuthenticationSuccessHandler или SimpleUrlAuthenticationSuccessHandler, может быть немного неуклюжим для реализации.В контроллере (например, метод POST, который обрабатывает логины), вы можете выполнить запрос заголовка самостоятельно;Например:

HttpServletRequest request =null;

String priorUrl = request.getHeader("Referer");

Вы заметите, что у вас будет URL до либо ручного (инициируемого пользователем) выхода из системы, либо времени ожидания сеанса(как обрабатывается сеансом Spring): вы получите https://iAmPriorUrl.com/....Тогда вы можете делать с ней все, что захотите.

0 голосов
/ 07 июня 2018

Используйте «Referer» из атрибута сеанса для получения последнего URL-адреса запроса.В моем приложении я использую это

public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    public static final String REDIRECT_URL_SESSION_ATTRIBUTE_NAME = "REDIRECT_URL";

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {

        Object redirectURLObject = request.getSession().getAttribute(REDIRECT_URL_SESSION_ATTRIBUTE_NAME);

        if(redirectURLObject != null)
            setDefaultTargetUrl(redirectURLObject.toString());
        else{
            setDefaultTargetUrl("/");
        }

        request.getSession().removeAttribute(REDIRECT_URL_SESSION_ATTRIBUTE_NAME);
        super.onAuthenticationSuccess(request, response, authentication);
    }

}

Редактировать:

Извините, я забыл показать контроллер входа

@RequestMapping(method = RequestMethod.GET, value = {"/login"})
    String login(Model model, Principal principal, HttpServletRequest request) throws Exception{
        String referer = request.getHeader("Referer"); //Get previous URL before call '/login'

        //save referer URL to session, for later use on CustomAuthenticationSuccesshandler
        request.getSession().setAttribute(CustomAuthenticationSuccessHandler.REDIRECT_URL_SESSION_ATTRIBUTE_NAME, referer); 


        return principal == null ?  "login" : "redirect:/"; 
    }
...