Ami*_*rma 4 java spring spring-security
我知道这个问题可以通过不同的解决方案找到。但我无法让它在我的项目中工作。
我们正在向用户发送邮件,其中包含在应用程序中执行某些操作的链接。当用户点击 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用的配置是:
@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());
}
Run Code Online (Sandbox Code Playgroud)
使用此配置的问题是,如果我请求 url 说“http:localhost:8080/showPage”,spring security 将导航到“http:localhost:8080/login”,并且我无法从原始 URL 捕获任何内容。当我尝试使用自定义变量 targetUrl 并在同一个 CustomLoginSuccessHandler 中使用它时,会出现同样的问题。
如果我采取了错误的方法或缺少其他内容,请告诉我
还尝试使用自定义入口点,但无法使用我的入口点进行重定向。
@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());
}
}
Run Code Online (Sandbox Code Playgroud)
控制器 :
@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;
}
Run Code Online (Sandbox Code Playgroud)
要登录,页面将导航到不同的域。我在成功登录后将重定向 URL 传递到该域,它将页面重定向回重定向 URL
<a href="https://domain/sso/identity/login?channel=abc&ru=${externalUrl.applicationUrl}login" >Sign In</a>
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
然后在您的 JSP 中您可以使用redirectUrl来动态构造您的 URL。
http://your.sso/login?url=${redirectUrl}
Run Code Online (Sandbox Code Playgroud)
您需要做的最后一件事是/login将其添加到受permitAll(). 如果不这样做,您将陷入循环或最后一个请求被覆盖并且始终指向登录页面。
.antMatchers("/privacyPolicy", "/faq", "/aboutus", "/termsofuse", "/feedback","/feedbackSubmit", "/contactSsm", "/resources/**", "/userReply", "/userReplySubmit", "/image", "/logoutExternal", "/closeit", "/login").permitAll()
Run Code Online (Sandbox Code Playgroud)
您不需要任何其他自定义类(例如EntryPoints 或AuthenticationSuccessHandler实现)。
然而,当您使用 SSO 时,最好研究与 SSO 解决方案的正确集成,而不是使用登录页面进行此黑客攻击。
| 归档时间: |
|
| 查看次数: |
9329 次 |
| 最近记录: |