Spring 自定义AuthenticationFailureHandler中的Flash属性
登录失败时,我想将用户重定向到错误页面,并显示有意义的错误消息。是否可以添加将传递给后续请求的闪存属性 下面给出的代码不起作用Spring 自定义AuthenticationFailureHandler中的Flash属性,spring,authentication,spring-security,Spring,Authentication,Spring Security,登录失败时,我想将用户重定向到错误页面,并显示有意义的错误消息。是否可以添加将传递给后续请求的闪存属性 下面给出的代码不起作用RequestContextUtils.getOutputFlashMap()返回null public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailu
RequestContextUtils.getOutputFlashMap()
返回null
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler
{
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException
{
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(request);
if (outputFlashMap != null)
{
outputFlashMap.put("error", "Error message");
}
response.sendRedirect(request.getContextPath() + "/error");
}
}
我猜它是空的,因为您是从过滤器链调用函数的,而flash映射是由Spring的
DispatcherServlet
维护的,此时请求还没有通过它
为什么不使用一个参数呢?i、 e
response.sendRedirect(request.getContextPath()+"/error?error=" + "Error Message");
我在Spring4.3.17中遇到了同样的问题,最终通过逐步阅读SpringWebMVC代码并对如何在正常框架之外集成Flash属性进行有根据的猜测,找到了一个解决方案。这是让它发挥作用的关键。我相信这种方法应该适用于Spring3.1.1+
package org.myorg.spring.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.support.SessionFlashMapManager;
@Component
public final class FlashAuthenticationFailureHandler implements AuthenticationFailureHandler
{
/**
* Flash attribute name to save on redirect.
*/
public static final String AUTHENTICATION_MESSAGE = "FLASH_AUTHENTICATION_MESSAGE";
public FlashAuthenticationFailureHandler()
{
return;
}
@Override
public void onAuthenticationFailure(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException exception) throws IOException, ServletException
{
if (exception != null)
{
final FlashMap flashMap = new FlashMap();
// Don't send the AuthenticationException object itself because it has no default constructor and cannot be re-instantiated.
flashMap.put(AUTHENTICATION_MESSAGE, exception.getMessage());
final FlashMapManager flashMapManager = new SessionFlashMapManager();
flashMapManager.saveOutputFlashMap(flashMap, request, response);
}
response.sendRedirect(request.getHeader("referer"));
return;
}
}
然后在需要flash属性的控制器中,只需添加一个同名的ModelAttribute:
@RequestMapping(value = {"/someview"}, method = RequestMethod.GET)
public String getSomePage(final Authentication authentication, @ModelAttribute(FlashAuthenticationFailureHandler.AUTHENTICATION_MESSAGE) final String authenticationMessage, final Model model) throws Exception
{
if (authenticationMessage != null)
{
model.addAttribute("loginMessage", authenticationMessage);
}
return "myviewname";
}
然后可以在JSP中访问包含消息的页面属性,如下所示:
<c:if test="${not empty loginMessage}">
<div class="alert alert-danger"><c:out value="${loginMessage}" /></div>
</c:if>
若并没有其他选项,这是可行的,但我不希望在查询字符串中透露我的参数。