登录后重定向到所需位置 [英] Redirect to desired location after login

查看:112
本文介绍了登录后重定向到所需位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题可以通过不同的解决方案找到。但是我无法在我的项目中使用它。

I know this question can be found with different solutions. But I am unable to get it working in my project.

我们正在向用户发送邮件,这些用户可以在应用程序中执行某些操作。当用户点击网址时,如果他没有登录,则应该重定向到登录页面,登录后应导航到目标网址。

We are sending mails to users which has link to perform some action in the application. When user click on url he should be redirect to login page if he is not logged in and after login should be navigated to the targeted URL.

我正在尝试修复使用CustomLoginSuccessHandler这里是代码。:

I am trying to fix using CustomLoginSuccessHandler here is the code.:

public class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
//    public CustomLoginSuccessHandler(String defaultTargetUrl) {
//        setDefaultTargetUrl(defaultTargetUrl);
//    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        HttpSession session = request.getSession(false);
        if (session != null) {
            String redirectUrl = (String) session.getAttribute("url_prior_login");
            if (redirectUrl != null) {
                // we do not forget to clean this attribute from session
                session.removeAttribute("url_prior_login");
                // then we redirect
                getRedirectStrategy().sendRedirect(request, response, redirectUrl);
            } else {
                super.onAuthenticationSuccess(request, response, authentication);
            }
        } else {
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }
}

我使用的配置是:

    @Bean
    public SavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler(){
        CustomLoginSuccessHandler successHandler = new CustomLoginSuccessHandler();
//        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
//        successHandler.setUseReferer(true);    getting NULL in the controller every time
//        successHandler.setTargetUrlParameter("targetUrl"); this also doesnt work as browser is redirect to /login page and URL parameters are lost
        return successHandler;
    }

protected void configure(HttpSecurity http) throws Exception {
        http
                .logout().logoutUrl("/logout").deleteCookies("JSESSIONID").logoutSuccessUrl("/logoutSuccess")
                .and()
                .authorizeRequests()
                .antMatchers("/privacyPolicy", "/faq", "/aboutus", "/termsofuse", "/feedback","/feedbackSubmit", "/contactSsm", "/resources/**", "/userReply", "/userReplySubmit", "/image", "/logoutExternal", "/closeit").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .successHandler(authenticationSuccessHandler)
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .permitAll();
//            .and().exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint());
    }

使用此配置的问题是,如果我请求url说'http:localhost :8080 / showPage'spring security导航到'http:localhost:8080 / login',我无法从原始URL捕获任何内容。当我尝试使用自定义变量targetUrl并在同一个CustomLoginSuccessHandler中使用它时会出现同样的问题。

Problem using this configuration is, If i request for url say 'http:localhost:8080/showPage' spring security is navigating to 'http:localhost:8080/login' and I am unable to capture anything from original URL. Same problem occurs when I try to use a custom variable targetUrl and using it in the same CustomLoginSuccessHandler.

请告诉我是否采取了错误的方法或缺少其他东西

Please let me know if am taking a wrong approach or something else is missing

还尝试使用Custom EntryPoint但无法使用我的入口点重定向。

Also tried using Custom EntryPoint but unable to redirect using my entrypoint.

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint{

    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        request.getSession().setAttribute("targetUrl",request.getRequestURL());
        redirectStrategy.sendRedirect(request,response,request.getRequestURL().toString());
    }
}

控制器:

@RequestMapping(value="/login")
public ModelAndView loginHandler(HttpServletRequest request) {
    ModelAndView mav = new ModelAndView();

    String targetUrl = request.getParameter("targetUrl");
    if(targetUrl!=null){ // targetUrl is always null as spring security is navigating to /login asd parameters are lost
        request.getSession().setAttribute("url_prior_login",targetUrl);
    }
    mav.setViewName("login");
    return mav;
}

要登录,页面将导航到其他域。成功登录后,我将重定向URL传递给该域,将页面重定向回redirecturl

To login, page is navigated to a different domain. and I pass a redirect URL to that domain after successful login it redirects the page back to the redirecturl

<a href="https://domain/sso/identity/login?channel=abc&ru=${externalUrl.applicationUrl}login" >Sign In</a>


推荐答案

Spring Security已使用 RequestCache 默认实现 HttpSessionRequestCache 将最后一个请求存储在HTTP会话中。您可以使用 SPRING_SECURITY_SAVED_REQUEST 属性名称访问它以从会话中获取它。

Spring Security already stores the request using a RequestCache the default implementation HttpSessionRequestCache stores the last request in the HTTP session. You can access it using the SPRING_SECURITY_SAVED_REQUEST attribute name to get it from the session.

在你的控制器中做这样的事情

Doing something like this in your controller

public ModelAndView login(HttpServletRequest req, HttpSession session) {
    ModelAndView mav = new ModelAndView("login");
    if (session != null) {
        SavedRequest savedRequest = session.getAttribute("SPRING_SECURITY_SAVED_REQUEST");
        if (savedRequest != null) {
            mav.addObject("redirectUrl", savedRequest.getRedirectUrl());
        }
    }
    return mav;
}

然后在JSP中你可以使用 redirectUrl 动态构建您的网址。

Then in your JSP you can use the redirectUrl to dynamically construct your URL.

http://your.sso/login?url=${redirectUrl}

你需要做的最后一件事就是让 / login <每个人都可以访问/ code>,将其添加到受 permitAll()保护的列表中。如果你不这样做,你将进入循环或最后一个请求被覆盖,并始终指向登录页面。

The final thing you need to do is to make /login accessible for everyone by adding it to the list which is protected by permitAll(). If you don't do this, you will get into a loop or the last request is overwritten and will always point to the login page.

.antMatchers("/privacyPolicy", "/faq", "/aboutus", "/termsofuse", "/feedback","/feedbackSubmit", "/contactSsm", "/resources/**", "/userReply", "/userReplySubmit", "/image", "/logoutExternal", "/closeit", "/login").permitAll()

您不需要任何其他自定义类,如 EntryPoint s或 AuthenticationSuccessHandler 实施。

You don't need any other custom classes like EntryPoints or AuthenticationSuccessHandler implementations.

然而,当您使用SSO时,最好调查与SSO解决方案的正确集成,而不是使用登录页面进行此黑客攻击。

However as you are using SSO it would be probably best to investigate a proper integration with the SSO solution instead of this hack with a login page.

这篇关于登录后重定向到所需位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆