我知道这个问题可以通过不同的解决方案找到。但我无法让它在我的项目中运作。
我们正在向用户发送邮件,这些用户可以在应用程序中执行某些操作。当用户点击网址时,如果他没有登录,则应该重定向到登录页面,登录后应导航到目标网址。
我正在尝试修复使用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 security正在导航到'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
<a href="https://domain/sso/identity/login?channel=abc&ru=${externalUrl.applicationUrl}login" >Sign In</a>
答案 0 :(得分:4)
Spring Security已使用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}
您需要做的最后一件事是通过将/login
添加到受permitAll()
保护的列表,使每个人都可以访问.antMatchers("/privacyPolicy", "/faq", "/aboutus", "/termsofuse", "/feedback","/feedbackSubmit", "/contactSsm", "/resources/**", "/userReply", "/userReplySubmit", "/image", "/logoutExternal", "/closeit", "/login").permitAll()
。如果你不这样做,你将进入循环或最后一个请求被覆盖,并始终指向登录页面。
EntryPoint
您不需要任何其他自定义类,例如AuthenticationSuccessHandler
或var res = list.Skip(noOfElementToSkip).Take(noOfElementsToTake);
实现。
但是,当您使用SSO时,最好调查与SSO解决方案的正确集成,而不是使用登录页面进行此黑客攻击。
答案 1 :(得分:0)
您至少会遇到一个问题:getSession(false)
。
的getSession() 返回与此请求关联的当前会话,或者如果请求没有会话,创建一个。
如果您希望在没有会话时返回空值,则应使用null
。
在您的情况下,您永远不会得到libxml2
会话。