登录后重定向到所需位置

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

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

我试图修复使用CustomLoginSuccessHandler这里是代码:

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安全性导航到’http:localhost:8080 / login’,我无法从原始URL捕获任何内容。 当我尝试使用自定义变量targetUrl并在同一CustomLoginSuccessHandler中使用它时,会出现同样的问题。

如果采取错误的方法或缺少其他东西,请告诉我

还尝试使用Custom 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

 Sign In 

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

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

 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动态构建URL。

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

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

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

您不需要任何其他自定义类,如EntryPointAuthenticationSuccessHandler实现。

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

你至少会HttpSession session = request.getSession();一个问题: HttpSession session = request.getSession();

getSession()返回与此请求关联的当前会话,或者如果请求没有会话,则创建一个会话。

如果您希望在没有会话的情况下返回null,则应使用getSession(false)

在你的情况下,你永远不会得到一个null会话。