setDefaultTargetUrl is not working

2019-08-26 21:42发布

问题:

I want to redirect my page based on some hidden value in login.jsp page, here is my code

public class AuthenticationHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    private final String HASH_URL = "hashURL";

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
        super.onAuthenticationSuccess(request, response, authentication);

        String hashValue = request.getParameter(HASH_URL);
        if(hashValue != null){
            if(!hashValue.isEmpty()){
                setDefaultTargetUrl("/home/" + hashValue);
            }
        }
    }
}

I can see that hashValue is getting latest values from login.jsp page, but its always moving the site /home/ page, here is my configs

<security:form-login
                login-page="/auth/login"
                default-target-url="/home/"
                authentication-success-handler-ref="customAuthenticationSuccessHandler"
                always-use-default-target="true"
                authentication-failure-url="/auth/login?error=true"/>

回答1:

I already quoted this in your previous problem Redirecting URL after user logged out to previous page opened

Following a successful authentication SavedRequestAwareAuthenticationSuccessHandler: 
If the alwaysUseDefaultTargetUrl property is set to true, the defaultTargetUrl 
will be used for the destination. 
Any DefaultSavedRequest stored in the session will be removed.

So you should set always-use-default-target="false" also you can remove default-target-url attribute.

Hope this helps.



回答2:

You shouldn't be calling setDefaultTargetUrl while your application is running. It's a field on the class, not a local variable, so it will apply to all users of your site.

Take a look at the code you are extending in SavedRequestAwareAuthenticationSuccessHandler. It's essential you understand how it works if you are going to call the superclass method. You call super.onAuthenticationSuccess as the first thing in your method. This will take the current value of defaultTargetUrl (or a cached request) and redirect to that URL. You are setting the property after the redirect has taken place.

As I said you shouldn't be setting the property at all at runtime. I's guess your method should be more like

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {

    String hashValue = request.getParameter(HASH_URL);
    if(hashValue != null) {
        response.sendRedirect(getDefaultTargetUrl() + "/" + hashValue;
    } else {
        response.sendRedirect(getDefaultTargetUrl());
    }
}

You probable don't need to extend a class at all. Just implement AuthenticationSuccessHandler directly yourself. It will be easier to understand what's going on without the inheritance involved.

Not that if you're using a custom handler class, namespace properties like always-use-default-target which affect the default handler won't have any effect.