3

我想知道如何使用自定义注销处理程序实现注销后重定向。我已经实现了一个 CustomLogoutSuccessHandler 但我无法访问以前由登录用户设置的 http 会话数据。数据总是空的......

class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {

    private static final ThreadLocal<Authentication> AUTH_HOLDER = new ThreadLocal<Authentication>()

    void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        AUTH_HOLDER.set authentication

        // reading session variable...
        request.session?.variable // but this is always empty

        try {
            super.handle(request, response, authentication)
        }
        finally {
            AUTH_HOLDER.remove()
        }
    }

    @Override
    protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = AUTH_HOLDER.get()

        String url = super.determineTargetUrl(request, response)

        // do something with the url based on session data..

        url
    }
}
4

1 回答 1

2

我不知道是否有任何简单的方法可以做到这一点,但提出了以下解决方案。

您所要做的就是在 LogoutSuccessHandler 中设置 setTargetUrlParameter。为此,我使用了 Lincoln Baxter 编写的 HttpServletRequestWrapper 的实现,此处为向当前请求添加参数。这是相关的代码。

public class PrettyFacesWrappedRequest extends HttpServletRequestWrapper
{
    private final Map<String, String[]> modifiableParameters;
    private Map<String, String[]> allParameters = null;

    /**
     * Create a new request wrapper that will merge additional parameters into
     * the request object without prematurely reading parameters from the
     * original request.
     * 
     * @param request
     * @param additionalParams
     */
    public PrettyFacesWrappedRequest(final HttpServletRequest request, 
                                                    final Map<String, String[]> additionalParams)
    {
        super(request);
        modifiableParameters = new TreeMap<String, String[]>();
        modifiableParameters.putAll(additionalParams);
    }

    @Override
    public String getParameter(final String name)
    {
        String[] strings = getParameterMap().get(name);
        if (strings != null)
        {
            return strings[0];
        }
        return super.getParameter(name);
    }

    @Override
    public Map<String, String[]> getParameterMap()
    {
        if (allParameters == null)
        {
            allParameters = new TreeMap<String, String[]>();
            allParameters.putAll(super.getParameterMap());
            allParameters.putAll(modifiableParameters);
        }
        //Return an unmodifiable collection because we need to uphold the interface contract.
        return Collections.unmodifiableMap(allParameters);
    }

    @Override
    public Enumeration<String> getParameterNames()
    {
        return Collections.enumeration(getParameterMap().keySet());
    }

    @Override
    public String[] getParameterValues(final String name)
    {
        return getParameterMap().get(name);
    }
}

然后在 CustomLogoutSuccessHandler 中,我将此 targetUrl 添加为参数,如下所示:

@Component
public class MyCustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
       HttpServletRequest wrappedRequest = request;

        if (authentication != null) {
           //do something with the Principal and add the corresponding url
           Map<String, String[]> extraParams = new TreeMap<String, String[]>();
           extraParams.put("targetUrl", new String[] {"/target.xhtml"});
           wrappedRequest = new PrettyFacesWrappedRequest(request, extraParams);
           setTargetUrlParameter("targetUrl");
        }
        setDefaultTargetUrl("/general/main.xhtml");
        super.onLogoutSuccess(wrappedRequest, response, authentication);       
    }
}

以及对 applicationContext 的相关更改:

<http>
    <logout logout-url="/j_spring_security_logout"
                success-handler-ref="myCustomLogoutSuccessHandler"
                invalidate-session="true"/>
</http>
<beans:bean id="myCustomLogoutSuccessHandler" class="com.examples.MyCustomLogoutSuccessHandler"/>
于 2012-09-22T00:36:04.410 回答