javaconfigurationstruts2interceptorinterceptorstack

Adding a custom interceptor for some actions


I have created an interceptor which I want to map to some particular methods in some action and I don't want to disturb the existing code:

struts.xml:

<package name="francis" namespace="/francis" extends="struts-default, json-default">
    <interceptors>             
        <interceptor name="authentication" class="main.java.com.commdel.commons.struts2.interceptors.AuthenticationInterceptor"/>            
        <interceptor name="authorization" class="main.java.com.commdel.commons.struts2.interceptors.SecurityInterceptor"/>

The custom interceptor csrf:

        <interceptor name="csrf" class="main.java.com.commdel.commons.struts2.interceptors.CsrfTokenInterceptor"/>           
        
        <interceptor-stack name="commonStack">
            <interceptor-ref name="authentication"/>
            <interceptor-ref name="authorization"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
     </interceptors> 
     <default-interceptor-ref name="commonStack"/>
    <global-results>
          <result name="error" type="velocity">/results/velocity/common/globalerror.vm</result>  
          <result name="AUTHORIZATIONERROR" type="velocity">/results/velocity/common/sessionError.vm</result>                        
      </global-results>

Mapping csrf to some action:

    <action name="addUpdateClaimHeadMetronic" class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" method="addUpdateClaimHead">
        <interceptor-ref name="csrf"/>
    </action>
</package> 

Solution

  • You seem to think that the default Interceptor Stack applies to all actions, and that the eventual interceptor you're specifying for to the single actions are added to the default stack. They're not.

    The default stack is the stack used for all the actions that does not specify any stack (or single interceptor, like in your case).

    If you want to add an interceptor, then specify also the stack it should add to,

    <action name="addUpdateClaimHeadMetronic" 
           class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" 
          method="addUpdateClaimHead">
    
        <interceptor-ref name="commonStack"/>
        <interceptor-ref name="csrf"/>
    </action>
    

    or define a new stack and use it:

    <interceptor-stack name="commonStack">
        <interceptor-ref name="authentication"/>
        <interceptor-ref name="authorization"/>
        <interceptor-ref name="defaultStack"/>
    </interceptor-stack>
    
    <interceptor-stack name="csrfStack">
        <interceptor-ref name="authentication"/>
        <interceptor-ref name="authorization"/>
        <interceptor-ref name="defaultStack"/>
        <interceptor-ref name="csrf"/>
    </interceptor-stack>
    
    ....
    
    <default-interceptor-ref name="commonStack"/>
    
    ....
    
    <action name="addUpdateClaimHeadMetronic" 
           class="main.java.com.commdel.francis.struts2.actions.ClaimHeadAction" 
          method="addUpdateClaimHead">
    
        <interceptor-ref name="csrfStack"/>
    </action>
    

    Note that the first approach violates DRY if you have a lot of actions sharing the secondary interceptor stack configuration, and it can be used only if your Interceptor is good to be placed as first or as last. If you need it in the middle (eg. after param, but before workflow) you have to define a stack by exploding the defaultStack, copying it from struts-default.xml.