FullAjaxExceptionHandler does not show session expired error page on ajax button

做~自己de王妃 提交于 2019-11-28 11:42:12
BalusC

You're sending a synchronous redirect as a response to the ajax request (a HTTP 302 response using e.g. response.sendRedirect()). This is not right. The JavaScript ajax engine treats the 302 response as a new destination to re-send the ajax request to. However, that in turn returns a plain vanilla HTML page instead of a XML document with instructions which parts of the page to update. This is confusing and thus the redirected response is altogether ignored. That explains precisely the symptoms you're facing.

The very same problem is also asked and answered in the following closely related questions:

Basically, you need to instruct Spring Security in some way to perform the following conditional check:

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
    // JSF ajax request. Return special XML response which instructs JavaScript that it should in turn perform a redirect.
    response.setContentType("text/xml");
    response.getWriter()
        .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
        .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
    // Normal request. Perform redirect as usual.
    response.sendRedirect(loginURL);
}

I'm however no Spring user and I'm not interested to use it, and am therefore not able to give a more detailed answer how to perform this check in Spring Security. I can however tell that Apache Shiro has exactly the same problem which is explained and solved in this blog article: Make Shiro JSF Ajax Aware.

In file spring-security (en el archivo de Spring Security)

<beans:bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>

<!-- redirection strategy -->
<beans:bean id="jsfRedirectStrategy" class="com.mycompany.JsfRedirectStrategy">
    <beans:property name="invalidSessionUrl" value="/login.xhtml" />
</beans:bean>

<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
    <beans:constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
    <beans:property name="invalidSessionStrategy" ref="jsfRedirectStrategy" />
</beans:bean>

<http auto-config='true' use-expressions="true">
    <intercept-url pattern="/login" access="permitAll"/>
    <intercept-url pattern="/ajaxErrorPage" access="permitAll"/>
    <intercept-url pattern="/pages/*" access="hasRole('admin')" />
    <intercept-url pattern="/j_spring_security_check" access="permitAll"/>        
    <logout logout-success-url="/login.xhtml" />
    <form-login login-page="/login.xhtml"
            login-processing-url="/j_spring_security_check"                                                       
            default-target-url="/pages/index.xhtml"
            always-use-default-target="true"                                                        
            authentication-failure-url="/login.xhtml"/>

     <!-- custom filter -->
    <custom-filter ref="sessionManagementFilter"  before="SESSION_MANAGEMENT_FILTER" />

</http>

The custom redirectStrategy (La estrategia de redirección personalizada)

public class JsfRedirectStrategy implements InvalidSessionStrategy
{

    private static final String FACES_REQUEST = "Faces-Request";

    private String invalidSessionUrl;

    public void setInvalidSessionUrl(String invalidSessionUrl) {
        this.invalidSessionUrl = invalidSessionUrl;
    }

    public String getInvalidSessionUrl() {
       return invalidSessionUrl;
    }



    @Override
    public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {



        String contextPath = request.getContextPath();
        String urlFinal = contextPath+invalidSessionUrl;




        if ("partial/ajax".equals(request.getHeader(FACES_REQUEST))) {
            // with ajax
            response.setContentType("text/xml");
            response.getWriter()
                .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
                .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", urlFinal);
        } else {

            // not ajax
            request.getSession(true);
            response.sendRedirect(urlFinal);

        }

   }

work for me.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!