Spring Security 302 redirection after primefaces commandbutton ajax failure on register page

Viewed 124

I have a problem with Spring Security and ajax request of primefaces commandbutton. After clicking commandbutton in my signup page and fail response, for next clicking, error 302 occured and return login page! I use primefaces 8.0 and spring security 5.

here is my security config:

<http auto-config="true" use-expressions="true">
    <access-denied-handler error-page="/accessDenied.xhtml"/>
    <form-login login-page="/login.xhtml"
                login-processing-url="/login"
                password-parameter="password"
                username-parameter="username"
                authentication-failure-url="/login.xhtml?error=true"/>
    <logout invalidate-session="true"
            logout-success-url="/"
            logout-url="/logout"/>
    <intercept-url pattern="/login.xhtml" access="permitAll"/>
    <!-- RESOURCES -->
    <intercept-url pattern="/skins/**" access="permitAll"/>
    <intercept-url pattern="/css/**" access="permitAll"/>
    <intercept-url pattern="/adf/**" access="permitAll"/>
    <intercept-url pattern="/images/**" access="permitAll"/>
    <intercept-url pattern="/js/**" access="permitAll"/>
    <intercept-url pattern="/javax.faces.resource/**" access="permitAll"/>
    <intercept-url pattern="/signup.xhtml" access="permitAll"/>
    <intercept-url pattern="/**" access="isAuthenticated()"/>
    <csrf/>
</http>

my signup.xhtml page :

<h:body class="blue-grey-theme">

<h:form id="form" prependId="false">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

            <p:growl id="smsGrowl" life="7000" globalOnly="true"/>

            <p:tabView id="applicantTab" widgetVar="tabView" effect="fade"
                       activeIndex="#{applicantSignUpBean.applicantSignUpModel.tabViewActiveIndex}"
                       style="margin-bottom:10px; text-align: right; width: 98%; min-width: 400px">

                <p:tab id="PersonalTab" title="#{bundle.personal_applicant}">
                    <h:panelGrid id="personalGrid" columns="4" cellpadding="5" style="width: 99%;"
                                 styleClass="ui-grid">

                        <app:outputLabel rendered="true" value="#{bundle.firstName}" required="true" for="fName"/>
                        <app:input id="fName" required="true" requiredMessage="#{bundle.firstname_required}"
                                   value="#{mySignUpBean.mySignUpModel.firstName}"
                                   style="width:250px"/>

                        <app:outputLabel rendered="true" value="#{bundle.lastName}" required="true" for="lName"/>
                        <app:input id="lName"
                                   value="#{mySignUpBean.mySignUpModel.lastName}"
                                   required="true" requiredMessage="#{bundle.lastname_required}"
                                   style="width:250px"/>

                    
                    <!-- ...... -->

                    </h:panelGrid>

                    <br/>
                    <p:outputPanel style="text-align: center; ">
                        <p:commandButton id="btnSavePersonal"
                                         actionListener="#{applicantSignUpBean.signUpPersonal}"
                                         icon="fa fa-save" value="#{bundle.registration}"
                                         process=":form:applicantTab:PersonalGrid  @this"
                                         update=":form:applicantTab:PersonalGrid"
                                         style="margin: 20px; width: 150px;" styleClass="button_save">

                        </p:commandButton>
                        <p:tooltip for="btnSavePersonal" value="#{bundle.save}"/>

                    </p:outputPanel>


                
                </p:tab>
            </p:tabView>

</h:form>

I tried several things but without success...

thanks for your help

1 Answers

Spring Security prevents CSRF attacks by requiring a randomly generated token as an HTTP parameter, but this breaks JSF commandButtons. However as JSF 2.2 already contains an explicit protection against CSRF attacks you can safely disable the Spring Security CSRF protection.

As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration. If you would like to disable CSRF protection, the corresponding XML configuration can be seen below.

<http>
    <!-- ... -->
    <csrf disabled="true"/>
</http>

For more see: Spring Security Configure CSRF Protection

EDIT

You can't signUp, login or logout using AJAX request, so you will have to use ajax=false on your btnSavePersonal commandButton, but this will break validators, messages and this method applicantSignUpBean.signUpPersonal will not be called, and you will have to move your business logic to Spring Beans.

Check this: PrimeFaces Spring Security Example

Related