issue with Struts2 interceptor order - struts2

I have a following interceptor stack defined
<interceptor-stack name="applicationStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="debugging"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="contextSecurityInterceptor" />
</interceptor-stack>
with this values from the UI are not getting submitted to the action, because of which "required" validation always fails.
if i change the order of interceptor to "workflow" first then "validation" as, values does get submitted and action gets executed without validating values.
what should be order of interceptors to keep the validation and data submission in order.
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.devMode" value="false" />
<constant name="struts.action.extension" value="action" />
<constant name="struts.custom.i18n.resources" value="global" />
<package name="org" namespace="/"
extends="struts-default,json-default">
<result-types>
<result-type name="tiles"
class="org.apache.struts2.views.tiles.TilesResult" />
</result-types>
<global-results>
<result name="welcome" type="tiles">welcome</result>
</global-results>
</package>
<package name="org.unsecureActions" extends="org">
<!--
This package contains such a actions which doesn't need user logged
in.
-->
<action name="welcome" method="forwardAction" class="baseAction">
<result name="success" type="tiles">welcome</result>
</action>
<action name="logoutCandidate" method="logoutCandidate" class="logoutAction">
<result name="success" type="tiles">welcome</result>
</action>
<action name="loadAdvanceSearchForm" method="loadAdvanceSearch"
class="advanceSearchAction">
<result name="success" type="tiles">advanceSearch</result>
</action>
<!--Candidate workflow actions -->
<action name="registerCandidateStep1" class="candidateAction"
method="registerCandidateStep1">
<result name="input" type="tiles">registerCandidate</result>
<result name="success" type="tiles">registerCandidate</result>
</action>
<action name="registerCandidateStep2" class="candidateAction"
method="registerCandidateStep2">
<result name="input" type="tiles">registerCandidate</result>
<result name="success" type="tiles">registerCandidate</result>
</action>
<action name="registerCandidateStep3" class="candidateAction"
method="registerCandidateStep3">
<result name="input" type="tiles">registerCandidate</result>
<result name="success" type="chain">
<param name="actionName">loginCandidate</param>
<param name="namespace">/org.unsecureActions</param>
</result>
</action>
<action name="loadCandidateRegistrationForm" class="loadCandidateFromAction"
method="loadCandidateRegistrationForm">
<result name="success" type="tiles">registerCandidate</result>
</action>
<!--Candidate workflow actions -->
<action name="loginCandidate" class="loginAction" method="loginCandidate">
<result name="success" type="tiles">home</result>
<result name="input" type="tiles">welcome</result>
</action>
</package>
<package name="org.secureActions" extends="org">
<!--
This package contains such a actions which needs user must logged in
before executing these.
-->
<action name="home" method="forwardAction" class="baseAction">
<result name="success" type="tiles">home</result>
</action>
<action name="loadAdvanceSearchForm" method="loadAdvanceSearch"
class="advanceSearchAction">
<result name="success" type="tiles">advanceSearch</result>
</action>
<action name="simpleSearch" method="simpleSearch" class="simpleSearchAction">
<result name="success" type="tiles">search</result>
<result name="input" type="tiles">home</result>
</action>
<action name="advanceSearch" method="advanceSearch" class="advanceSearchAction">
<result name="success" type="tiles">search</result>
</action>
<action name="loadImage" method="loadImage" class="imageAction">
<result name="imageData" type="stream">
<param name="contentType">${imageContentType}</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">filename="candidate.jpeg"</param>
<param name="bufferSize">${myBufferSize}</param>
</result>
</action>
</package>
</struts>

Neither the "validation" nor "workflow" interceptors are responsible for setting parameters on the action, that's done by the "params" interceptor.
"Workflow" only makes sense after "validation" because it checks to see if any errors are present on the action, and if there are, goes to the input result (by default).
The configuration you show is the default configuration plus your interceptor (which is suspiciously towards the end for something called "security").
If you're not seeing values being set on the action then something else is wrong, because the default configuration works as-is--so it's either something with your interceptor, the existing application flow, etc.

Related

Struts2 list of default interceptors

I can't find the list of interceptors used in the defaultStack. My app works when I use the defaultStack but I don't want to have all the interceptors, only the ones I need (like I don't want the CSP interceptor contained in the defaultStack).
Where can I find this list?
My bad, we can find it in struts-default.xml:
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="cspInterceptor">
<param name="enforcingMode">false</param>
</interceptor-ref>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params"/>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="coepInterceptor">
<param name="enforcingMode">false</param>
<param name="disabled">false</param>
<param name="exemptedPaths"/>
</interceptor-ref>
<interceptor-ref name="coopInterceptor">
<param name="exemptedPaths"/>
<param name="mode">same-origin</param>
</interceptor-ref>
<interceptor-ref name="fetchMetadata"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
</interceptor-stack>

How to configuration multiple actions using wildcard

It is possible to map multiple actions url in a single action configuration with wildcard ? I can able to do like */* */*/* in action names. But I don't know exactly how many nested path will come.
Since all my urls load render CommonLayout. So, I don't want to add multiple entries.
What I am doing now
<package name="myapp" extends="default" namespace="/">
<global-results>
<result type="tiles">CommonLayout</result>
</global-results>
<action name="a" />
<action name="a/create" />
<action name="b" />
<action name="b/customize" />
<action name="b/customize/app" />
<action name="d/create" />
<action name="d/view" />
<action name="d/view/list" />
</package>
Below is the configuration which I want to have, But It is not working for all nested actions.
<package name="myapp" extends="default" namespace="/">
<global-results>
<result type="tiles">CommonLayout</result>
</global-results>
<action name="*" />
</package>

How to use token between action chains, properly?

I have an action which I should protect it from CSRF attack. I have used Strut's tokenSession Interceptor to achieve this.
<action name="showBranchSelection" class="action.Request.BranchSelectionAction"
method="showBranchSelection">
<interceptor-ref name="tokenSession" />
<interceptor-ref name="basicStack" />
<result name="success">
/jsp/customer/request/branchSelection.jsp
</result>
</action>
and works great where this action has been called directly from jsp.
<s:form id="frmRequestShowBranchSelection" action="../../showBranchSelection" method="post" theme="simple" onsubmit="return false;">
<s:token name="tknRequestShowBranchSelection" />
<s:submit />
</s:form>
But I also have other actions (protected and not protected) which will be chained to this action in some situations.
<!-- not protected action chains to protected one -->
<action name="entranceCustomerLoginAction" class="action.Request.CustomerLoginAction"
method="entrance">
<result name="success">/jsp/login/success.jsp</result>
<result name="showBranchSelection" type="chain"> showBranchSelection
</result>
</action>
<!-- protected action chains to another protected one -->
<action name="continueReimTable" class="action.Request.ReimburseTableControllerAction"
method="continueReimTable">
<interceptor-ref name="tokenSession" />
<interceptor-ref name="basicStack" />
<result name="showBranchSelection" type="chain">
showBranchSelection
</result>
<result name="success" type="chain">
showBranchPage
</result>
</action>
What's the proper way to use token in such chains?! i.e. in both, when a not protected action chains to a protected action and when a protected action chains to another protected action.

unable to include token in jsp struts2

I am a beginner to struts2. i am using struts2 token interceptor to prevent CSRF. the token interceptor in working for the login page, but it is not working for the second page. the second page is just a JSP with hyperlinks, and when i change the token value it says "Could not find token name in params" . this is my code
Jsp
<div style="margin: 0 auto; font-size: 16px;">
<s:token />
<a href="<s:url value="view" />" >Click Here to View and Search Data</a>
<br/><br/>
<a href="<s:url value="Upload.jsp" />" >Click here to Upload Data (CSV format)</a>
<br/><br/>
<a href="<s:url value="Register.jsp" />" >Click here to Upload Data (FORM)</a>
</div>
Struts.xml
<package name="default" extends="struts-default, json-default">
<!-- CREATING INTERCEPTOR -->
<interceptors>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="tokenSession" />
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
<interceptor-ref name="fileUpload" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>
<global-results>
<result name="invalid.token">/error.jsp</result>
</global-results>
<action name="login" class="action.loginAction">
<result name="input">/Login.jsp</result>
<result name="success">/Main.jsp</result>
<result name="error">/error.jsp</result>
</action>
how do i implement token intercepto for this jsp.
please suggest
Try changing order of interceptors , keep defaultStack in last.
<interceptors>
<interceptor-stack name="myStack">
<interceptor-ref name="tokenSession" />
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
<interceptor-ref name="fileUpload" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
Try using token instead of tokenSession.
<interceptor-ref name="token" />
Also post the struts mapping for second page submit.

FileUploadInterceptor didn't intercept the large file

After a large file is uploaded, I only get the warning message in my console but it didn't stop me, the message is as follow:
WARN FileUploadInterceptor:56 - The file is to large to be uploaded:
_7fa0eae6b3a9b769f938dd52c0fde541_imgThumb "170587_10150170888553504_2474786_o.jpg"
"upload__24f6477e_140de810828__8000_00000008.tmp" 415411
Here is my Struts.xml setting:
<constant name="struts.multipart.maxSize" value="20480000" />
...
<package name="Image" extends="json-default,struts-default,my-default">
...
<action name="saveImage" class="example.Test" method="saveImg">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="exception"/>
<interceptor-ref name="fileUpload">
<param name="maximumSize">1</param>
<param name="allowedTypes">image/tiff,image/jpeg</param>
</interceptor-ref>
<interceptor-ref name="params" />
<interceptor-ref name="validation" />
<interceptor-ref name="json">
<param name="contentType">application/json</param>
</interceptor-ref>
<result name="success" type="json">
<param name="root">save</param>
</result>
<result name="error" type="json">
<param name="root">save</param>
</result>
<result name="invalid.token">/WEB-INF/jsp/invalidToken.jsp</result>
</action>
Any help would be appreciated!
You are including the File Upload Interceptor twice, because it is already present in the Default Stack.
The Default Stack is defined as:
<!-- A complete stack with all the common interceptors in place.
Generally, this stack should be the one you use, though it
may do more than you need. Also, the ordering can be
switched around (ex: if you wish to have your servlet-related
objects applied before prepare() is called, you'd need to move
servletConfig interceptor up.
This stack also excludes from the normal validation and workflow
the method names input, back, and cancel. These typically are
associated with requests that should not be validated.
-->
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
</interceptor-stack>
Then what you are actually defining for your Action is
<action name="saveImage" class="example.Test" method="saveImg">
<!-- DEFAULT STACK IMPORT EXPLODED -->
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
<!-- YOUR ADDITIONAL SETTINGS -->
<interceptor-ref name="exception"/>
<interceptor-ref name="fileUpload">
<param name="maximumSize">1</param>
<param name="allowedTypes">image/tiff,image/jpeg</param>
</interceptor-ref>
<interceptor-ref name="params" />
<interceptor-ref name="validation" />
<interceptor-ref name="json">
<param name="contentType">application/json</param>
</interceptor-ref>
<result name="success" type="json">
<param name="root">save</param>
</result>
<result name="error" type="json">
<param name="root">save</param>
</result>
<result name="invalid.token">/WEB-INF/jsp/invalidToken.jsp</result>
</action>
As you can see, many Interceptors are defined twice. Simply create an custom Interceptor Stack, and use it in all the Actions you need, or specify the Interceptors manually without including the Default Stack.
Something like
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload">
<param name="maximumSize">1</param>
<param name="allowedTypes">image/tiff,image/jpeg</param>
</interceptor-ref>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
<interceptor-ref name="json">
<param name="contentType">application/json</param>
</interceptor-ref>

Resources