Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic post logout redirection url based on user?

i am wondering how i could implement a post logout redirection using a custom logout handler. I have implemented a CustomLogoutSuccessHandler but i have no way off access http session data that has previous been set by the user who has logged in. The data is alway empty...

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
    }
}
like image 696
Marco Avatar asked Mar 31 '26 14:03

Marco


1 Answers

I do not know if there is any easy way to do this but came up with the below solution.

All you have to do is set the setTargetUrlParameter in your LogoutSuccessHandler. For that I made use of the implementation of HttpServletRequestWrapper written by Lincoln Baxter, III here for adding a parameter to the current request. Here is the relevant code.

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);
    }
}

and then in the CustomLogoutSuccessHandler, I add this targetUrl as the parameter like this:

@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);       
    }
}

and the relevant change to the 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"/>
like image 195
Ravi Kadaboina Avatar answered Apr 03 '26 04:04

Ravi Kadaboina