Q:

HTTP Status 405 - Request method 'POST' not supported Spring MVC

The scenario is user select some product and then click to do payment. Here I redirect him/her to IPG ( Internet Payment Gateway of Bank) and also pass my return url when payment is complete and finalize purchase order. every thing work fine until I add my spring security.
but if in some internal view post this url every thing is work fine again .
this is work fine ( spring security enable and every thing is work fine )
<form:form method="post" name="saleform" id="saleform"
    action="http://localhost:8080/Click2Pay/salecomplete">
    <input class="btn btn-primary" type="submit" value=" SaleComplete "
        id="btnsalecomplete" name="btnsalecomplete" />

</form:form>

    @RequestMapping(value = "/salecomplete", method = RequestMethod.POST)
        public String salecomplete(HttpServletRequest request,
                HttpServletResponse response, Model m)
                throws
<http auto-config="true" use-expressions="true">
        <intercept-url pattern="/admin/**" access="hasRole('admin')" />
        <access-denied-handler error-page="/403" />
        <form-login login-page="/login" default-target-url="/admin/admin"
            authentication-failure-url="/login?error" username-parameter="username"
            password-parameter="password" />
        <logout logout-success-url="/login?logout" />
        <!-- enable csrf protection -->
        <csrf />
    </http>

<authentication-manager>
        <authentication-provider user-service-ref="UserAuthenService">
            <password-encoder hash="sha" />
        </authentication-provider>
    </authentication-manager>

view source of IPG of bank in browser (https://pna.shaparak.ir/CardServices/paymentSuccess.html)
<form action="http&#x3a;&#x2f;&#x2f;localhost&#x3a;8080&#x2f;Click2Pay&#x2f;salecomplete"
    method="post" autocomplete="off">
    <div class="commandBar">

            <input type="hidden" name="redirectURL" id="redirectURL"
                value="http&#x3a;&#x2f;&#x2f;localhost&#x3a;8080&#x2f;Click2Pay&#x2f;salecomplete" />

            <input type="hidden" name="MID" id="MID" value="01134254" />

            <input type="hidden" name="ResNum" id="ResNum" value="162" />

            <input type="hidden" name="RefNum" id="RefNum"
                value="00000000021278797788" /> <input type="hidden"
                name="CustomerRefNum" id="CustomerRefNum" value="421320082083" />

            <input type="hidden" name="State" id="State" value="OK" /> <input
                type="hidden" name="language" id="language" value="fa" /> <input
                type="hidden" name="CardPanHash" id="CardPanHash"
                value="417bf6657c3830d051b4e9bab45203508c386787d4c083244c4dbac82bd559b8" />
            <input type="submit" value="تکمیل خرید"
                class="button btn btn-success btn-lg" name="Submit" />

            <input type="button" value="لغو خرید"
                class="button btn btn-default btn-lg" name="cancelButton"
                id="cancelButton" onclick="document.forms['returnForm'].submit();" />

    </div>

    </form>

what is the problem?

A:

If the bank site is posting back to your application then that is cross site request and the bank needs the csrf token which is not present in the bank's form. Try temporary disabling csrf protection to verify.
Solutions would be:

pass the CSRF token to bank's form somehows
disable CSRF protection for that specific request by supplying custom request matcher for csrf protected urls:
<csrf request-matcher-ref="someRequestMatcher" />
turn off CSRF protection completely (this would make it work but would make the application vulnerable to CSRF attacks)

