This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch feature/WW-5504-request-nonce
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 471e4e72152b95ce01098e79d0f0891b0c68b302
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Sun Jan 5 14:28:07 2025 +0100

    WW-5504 Allows to use request instead of session attribute to store nonce
---
 .../StrutsDefaultConfigurationProvider.java        |  6 +-
 .../opensymphony/xwork2/inject/ContainerImpl.java  |  8 +-
 .../java/org/apache/struts2/StrutsConstants.java   |  7 ++
 .../java/org/apache/struts2/components/UIBean.java | 18 +++--
 .../config/StrutsBeanSelectionProvider.java        |  3 +
 .../struts2/interceptor/csp/CspNonceReader.java    | 76 +++++++++++++++++++
 .../struts2/interceptor/csp/CspNonceSource.java    | 27 +++++++
 .../interceptor/csp/DefaultCspSettings.java        | 73 ++++++++++++------
 .../interceptor/csp/StrutsCspNonceReader.java      | 87 ++++++++++++++++++++++
 .../org/apache/struts2/default.properties          |  3 +
 core/src/main/resources/struts-beans.xml           |  3 +
 .../org/apache/struts2/components/UIBeanTest.java  | 37 +++++++++
 .../struts2/views/java/simple/ActionErrorTest.java |  3 +
 .../views/java/simple/ActionMessageTest.java       |  3 +
 .../struts2/views/java/simple/AnchorTest.java      |  3 +
 .../struts2/views/java/simple/CheckboxTest.java    |  3 +
 .../views/java/simple/DateTextFieldTest.java       |  3 +
 .../struts2/views/java/simple/FieldErrorTest.java  |  3 +
 .../apache/struts2/views/java/simple/FileTest.java |  3 +
 .../apache/struts2/views/java/simple/FormTest.java |  3 +
 .../apache/struts2/views/java/simple/HeadTest.java |  3 +
 .../struts2/views/java/simple/HiddenTest.java      |  3 +
 .../struts2/views/java/simple/LabelTest.java       |  3 +
 .../apache/struts2/views/java/simple/LinkTest.java |  3 +
 .../struts2/views/java/simple/PasswordTest.java    | 14 ++--
 .../struts2/views/java/simple/ResetTest.java       |  3 +
 .../struts2/views/java/simple/ScriptTest.java      |  3 +
 .../struts2/views/java/simple/SelectTest.java      |  3 +
 .../struts2/views/java/simple/SubmitTest.java      |  3 +
 .../struts2/views/java/simple/TextAreaTest.java    |  3 +
 .../struts2/views/java/simple/TextFieldTest.java   |  3 +
 .../struts2/views/java/simple/TokenTest.java       |  3 +
 32 files changed, 379 insertions(+), 40 deletions(-)

diff --git 
a/core/src/main/java/com/opensymphony/xwork2/config/providers/StrutsDefaultConfigurationProvider.java
 
b/core/src/main/java/com/opensymphony/xwork2/config/providers/StrutsDefaultConfigurationProvider.java
index 6e66dd7a3..81b7b4078 100644
--- 
a/core/src/main/java/com/opensymphony/xwork2/config/providers/StrutsDefaultConfigurationProvider.java
+++ 
b/core/src/main/java/com/opensymphony/xwork2/config/providers/StrutsDefaultConfigurationProvider.java
@@ -68,6 +68,8 @@ import com.opensymphony.xwork2.validator.ValidatorFileParser;
 import ognl.PropertyAccessor;
 import org.apache.struts2.dispatcher.HttpParameters;
 import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.interceptor.csp.CspNonceReader;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 import org.apache.struts2.interceptor.exec.ExecutorProvider;
 import org.apache.struts2.interceptor.exec.StrutsExecutorProvider;
 import org.apache.struts2.url.QueryStringBuilder;
@@ -159,7 +161,9 @@ public class StrutsDefaultConfigurationProvider implements 
ConfigurationProvider
                 .factory(UrlEncoder.class, StrutsUrlEncoder.class, 
Scope.SINGLETON)
                 .factory(UrlDecoder.class, StrutsUrlDecoder.class, 
Scope.SINGLETON)
 
-                .factory(ExecutorProvider.class, StrutsExecutorProvider.class, 
Scope.SINGLETON);
+                .factory(ExecutorProvider.class, StrutsExecutorProvider.class, 
Scope.SINGLETON)
+
+                .factory(CspNonceReader.class, StrutsCspNonceReader.class, 
Scope.SINGLETON);
 
         for (Map.Entry<String, Object> entry : 
DefaultConfiguration.BOOTSTRAP_CONSTANTS.entrySet()) {
             props.setProperty(entry.getKey(), 
String.valueOf(entry.getValue()));
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java 
b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java
index 455f8a449..1596077ab 100644
--- a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java
+++ b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java
@@ -419,8 +419,12 @@ class ContainerImpl implements Container {
                 // First time through...
                 constructionContext.startConstruction();
                 try {
-                    final Object[] parameters = getParameters(constructor, 
context, parameterInjectors);
-                    t = constructor.newInstance(parameters);
+                    if (constructor.getParameterCount() > 0 && 
parameterInjectors == null) {
+                        t = constructor.newInstance(new 
Object[constructor.getParameterCount()]);
+                    } else {
+                        final Object[] parameters = getParameters(constructor, 
context, parameterInjectors);
+                        t = constructor.newInstance(parameters);
+                    }
                     constructionContext.setProxyDelegates(t);
                 } finally {
                     constructionContext.finishConstruction();
diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java 
b/core/src/main/java/org/apache/struts2/StrutsConstants.java
index 91b8eb2f4..44cb01468 100644
--- a/core/src/main/java/org/apache/struts2/StrutsConstants.java
+++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java
@@ -509,4 +509,11 @@ public final class StrutsConstants {
 
     /** See {@link org.apache.struts2.interceptor.exec.ExecutorProvider} */
     public static final String STRUTS_EXECUTOR_PROVIDER = 
"struts.executor.provider";
+
+    /**
+     * See {@link org.apache.struts2.interceptor.csp.CspNonceReader}
+     * @since 6.8.0
+     */
+    public static final String STRUTS_CSP_NONCE_READER = 
"struts.csp.nonce.reader";
+    public static final String STRUTS_CSP_NONCE_SOURCE = 
"struts.csp.nonce.source";
 }
diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java 
b/core/src/main/java/org/apache/struts2/components/UIBean.java
index e525b92a7..967508426 100644
--- a/core/src/main/java/org/apache/struts2/components/UIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/UIBean.java
@@ -33,6 +33,7 @@ import org.apache.struts2.components.template.TemplateEngine;
 import org.apache.struts2.components.template.TemplateEngineManager;
 import org.apache.struts2.components.template.TemplateRenderingContext;
 import org.apache.struts2.dispatcher.StaticContentLoader;
+import org.apache.struts2.interceptor.csp.CspNonceReader;
 import org.apache.struts2.util.ComponentUtils;
 import org.apache.struts2.util.TextProviderHelper;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
@@ -40,7 +41,6 @@ import org.apache.struts2.views.util.ContextUtil;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 import java.io.Writer;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -521,6 +521,8 @@ public abstract class UIBean extends Component {
 
     protected TemplateEngineManager templateEngineManager;
 
+    protected CspNonceReader cspNonceReader;
+
     @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
     public void setDefaultTemplateDir(String dir) {
         this.defaultTemplateDir = dir;
@@ -546,6 +548,11 @@ public abstract class UIBean extends Component {
         this.templateEngineManager = mgr;
     }
 
+    @Inject
+    public void setCspNonceReader(CspNonceReader cspNonceReader) {
+        this.cspNonceReader = cspNonceReader;
+    }
+
     @Override
     public boolean end(Writer writer, String body) {
         evaluateParams();
@@ -864,13 +871,12 @@ public abstract class UIBean extends Component {
         }
 
         // to be used with the CSP interceptor - adds the nonce value as a 
parameter to be accessed from ftl files
-        HttpSession session = 
stack.getActionContext().getServletRequest().getSession(false);
-        Object nonceValue = session != null ? session.getAttribute("nonce") : 
null;
+        CspNonceReader.NonceValue nonceValue = 
cspNonceReader.readNonceValue(stack);
 
-        if (nonceValue != null) {
-            addParameter("nonce", nonceValue.toString());
+        if (nonceValue.isNonceValueSet()) {
+            addParameter("nonce", nonceValue.getNonceValue());
         } else {
-            LOG.debug("Session is not active, cannot obtain nonce value");
+            LOG.debug("Nonce not defined in: {}", nonceValue.getSource());
         }
 
         evaluateExtraParams();
diff --git 
a/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java 
b/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java
index a52a67749..e914b0452 100644
--- 
a/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java
+++ 
b/core/src/main/java/org/apache/struts2/config/StrutsBeanSelectionProvider.java
@@ -69,6 +69,7 @@ import org.apache.struts2.dispatcher.DispatcherErrorHandler;
 import org.apache.struts2.dispatcher.StaticContentLoader;
 import org.apache.struts2.dispatcher.mapper.ActionMapper;
 import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
+import org.apache.struts2.interceptor.csp.CspNonceReader;
 import org.apache.struts2.interceptor.exec.ExecutorProvider;
 import org.apache.struts2.ognl.OgnlGuard;
 import org.apache.struts2.url.QueryStringBuilder;
@@ -450,6 +451,8 @@ public class StrutsBeanSelectionProvider extends 
AbstractBeanSelectionProvider {
 
         alias(ExecutorProvider.class, 
StrutsConstants.STRUTS_EXECUTOR_PROVIDER, builder, props, Scope.SINGLETON);
 
+        alias(CspNonceReader.class, StrutsConstants.STRUTS_CSP_NONCE_READER, 
builder, props, Scope.SINGLETON);
+
         switchDevMode(props);
     }
 
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceReader.java 
b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceReader.java
new file mode 100644
index 000000000..de1412465
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceReader.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.interceptor.csp;
+
+import org.apache.struts2.util.ValueStack;
+
+/**
+ * Reads the nonce value using the ValueStack, {@link StrutsCspNonceReader} is 
the default implementation
+ * @since 6.8.0
+ */
+public interface CspNonceReader {
+
+    NonceValue readNonceValue(ValueStack stack);
+
+    class NonceValue {
+        private final String nonceValue;
+        private final CspNonceSource source;
+
+        private NonceValue(String nonceValue, CspNonceSource source) {
+            this.nonceValue = nonceValue;
+            this.source = source;
+        }
+
+        public static NonceValue ofSession(String nonceValue) {
+            return new NonceValue(nonceValue, CspNonceSource.SESSION);
+        }
+
+        public static NonceValue ofRequest(String nonceValue) {
+            return new NonceValue(nonceValue, CspNonceSource.REQUEST);
+        }
+
+        public static NonceValue ofNullSession() {
+            return new NonceValue(null, CspNonceSource.REQUEST);
+        }
+
+        public static NonceValue ofNullRequest() {
+            return new NonceValue(null, CspNonceSource.REQUEST);
+        }
+
+        public boolean isNonceValueSet() {
+            return nonceValue != null;
+        }
+
+        public String getNonceValue() {
+            return nonceValue;
+        }
+
+        public CspNonceSource getSource() {
+            return source;
+        }
+
+        @Override
+        public String toString() {
+            return "NonceValue{" +
+                    String.format("nonceValue='%s**********'", 
nonceValue.substring(0, 4)) +
+                    ", source=" + source +
+                    '}';
+        }
+    }
+}
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceSource.java 
b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceSource.java
new file mode 100644
index 000000000..cc34e3581
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/csp/CspNonceSource.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.interceptor.csp;
+
+/**
+ * Source of the nonce value
+ */
+public enum CspNonceSource {
+    REQUEST,
+    SESSION
+}
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java 
b/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java
index b245ab352..599409b0d 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/csp/DefaultCspSettings.java
@@ -18,8 +18,11 @@
  */
 package org.apache.struts2.interceptor.csp;
 
+import com.opensymphony.xwork2.inject.Inject;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.action.CspSettingsAware;
 
 import javax.servlet.http.HttpServletRequest;
@@ -43,15 +46,27 @@ import static java.lang.String.format;
  */
 public class DefaultCspSettings implements CspSettings {
 
-    private final static Logger LOG = 
LogManager.getLogger(DefaultCspSettings.class);
+    private static final Logger LOG = 
LogManager.getLogger(DefaultCspSettings.class);
+    private static final String NONCE_KEY = "nonce";
 
     private final SecureRandom sRand = new SecureRandom();
 
+    private CspNonceSource nonceSource = CspNonceSource.SESSION;
+
     protected String reportUri;
     protected String reportTo;
     // default to reporting mode
     protected String cspHeader = CSP_REPORT_HEADER;
 
+    @Inject(value = StrutsConstants.STRUTS_CSP_NONCE_SOURCE, required = false)
+    public void setNonceSource(String nonceSource) {
+        if (StringUtils.isBlank(nonceSource)) {
+            this.nonceSource = CspNonceSource.SESSION;
+        } else {
+            this.nonceSource = 
CspNonceSource.valueOf(nonceSource.toUpperCase());
+        }
+    }
+
     @Override
     public void addCspHeaders(HttpServletResponse response) {
         throw new UnsupportedOperationException("Unsupported implementation, 
use #addCspHeaders(HttpServletRequest request, HttpServletResponse response)");
@@ -59,40 +74,54 @@ public class DefaultCspSettings implements CspSettings {
 
     @Override
     public void addCspHeaders(HttpServletRequest request, HttpServletResponse 
response) {
+        if (this.nonceSource == CspNonceSource.SESSION) {
+            addCspHeadersWithSession(request, response);
+        } else if (this.nonceSource == CspNonceSource.REQUEST) {
+            addCspHeadersWithRequest(request, response);
+        } else {
+            LOG.warn("Unknown nonce source: {}, ignoring CSP settings", 
nonceSource);
+        }
+    }
+
+    private void addCspHeadersWithSession(HttpServletRequest request, 
HttpServletResponse response) {
         if (isSessionActive(request)) {
             LOG.trace("Session is active, applying CSP settings");
-            associateNonceWithSession(request);
+            request.getSession().setAttribute(NONCE_KEY, generateNonceValue());
             response.setHeader(cspHeader, createPolicyFormat(request));
         } else {
-            LOG.trace("Session is not active, ignoring CSP settings");
+            LOG.debug("Session is not active, ignoring CSP settings");
         }
     }
 
+    private void addCspHeadersWithRequest(HttpServletRequest request, 
HttpServletResponse response) {
+        request.setAttribute(NONCE_KEY, generateNonceValue());
+        response.setHeader(cspHeader, createPolicyFormat(request));
+    }
+
     private boolean isSessionActive(HttpServletRequest request) {
         return request.getSession(false) != null;
     }
 
-    private void associateNonceWithSession(HttpServletRequest request) {
-        String nonceValue = 
Base64.getUrlEncoder().encodeToString(getRandomBytes());
-        request.getSession().setAttribute("nonce", nonceValue);
+    private String generateNonceValue() {
+        return Base64.getUrlEncoder().encodeToString(getRandomBytes());
     }
 
     protected String createPolicyFormat(HttpServletRequest request) {
         StringBuilder policyFormatBuilder = new StringBuilder()
-            .append(OBJECT_SRC)
-            .append(format(" '%s'; ", NONE))
-            .append(SCRIPT_SRC)
-            .append(" 'nonce-%s' ") // nonce placeholder
-            .append(format("'%s' ", STRICT_DYNAMIC))
-            .append(format("%s %s; ", HTTP, HTTPS))
-            .append(BASE_URI)
-            .append(format(" '%s'; ", NONE));
+                .append(OBJECT_SRC)
+                .append(format(" '%s'; ", NONE))
+                .append(SCRIPT_SRC)
+                .append(" 'nonce-%s' ") // nonce placeholder
+                .append(format("'%s' ", STRICT_DYNAMIC))
+                .append(format("%s %s; ", HTTP, HTTPS))
+                .append(BASE_URI)
+                .append(format(" '%s'; ", NONE));
 
         if (reportUri != null) {
             policyFormatBuilder
-                .append(REPORT_URI)
-                .append(format(" %s; ", reportUri));
-            if(reportTo != null) {
+                    .append(REPORT_URI)
+                    .append(format(" %s; ", reportUri));
+            if (reportTo != null) {
                 policyFormatBuilder
                         .append(REPORT_TO)
                         .append(format(" %s; ", reportTo));
@@ -103,7 +132,7 @@ public class DefaultCspSettings implements CspSettings {
     }
 
     protected String getNonceString(HttpServletRequest request) {
-        Object nonce = request.getSession().getAttribute("nonce");
+        Object nonce = request.getSession().getAttribute(NONCE_KEY);
         return Objects.toString(nonce);
     }
 
@@ -133,10 +162,10 @@ public class DefaultCspSettings implements CspSettings {
     @Override
     public String toString() {
         return "DefaultCspSettings{" +
-            "reportUri='" + reportUri + '\'' +
-            ", reportTo='" + reportTo + '\'' +
-            ", cspHeader='" + cspHeader + '\'' +
-            '}';
+                "reportUri='" + reportUri + '\'' +
+                ", reportTo='" + reportTo + '\'' +
+                ", cspHeader='" + cspHeader + '\'' +
+                '}';
     }
 
 }
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/csp/StrutsCspNonceReader.java
 
b/core/src/main/java/org/apache/struts2/interceptor/csp/StrutsCspNonceReader.java
new file mode 100644
index 000000000..3de7afdfd
--- /dev/null
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/csp/StrutsCspNonceReader.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.interceptor.csp;
+
+import com.opensymphony.xwork2.inject.Inject;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.util.ValueStack;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Reads nonce value from session or request attribute.
+ * @since 6.8.0
+ */
+public class StrutsCspNonceReader implements CspNonceReader {
+
+    private static final Logger LOG = 
LogManager.getLogger(StrutsCspNonceReader.class);
+
+    private final CspNonceSource nonceSource;
+
+    @Inject(value = StrutsConstants.STRUTS_CSP_NONCE_SOURCE, required = false)
+    public StrutsCspNonceReader(String source) {
+        if (StringUtils.isBlank(source)) {
+            this.nonceSource = CspNonceSource.SESSION;
+        } else {
+            this.nonceSource = CspNonceSource.valueOf(source.toUpperCase());
+        }
+    }
+
+    @Override
+    public NonceValue readNonceValue(ValueStack stack) {
+        HttpServletRequest request = 
stack.getActionContext().getServletRequest();
+        NonceValue nonceValue;
+
+        if (nonceSource == CspNonceSource.SESSION) {
+            LOG.debug("Reading nonce value from session");
+            nonceValue = readNonceFromSession(request);
+        } else if (nonceSource == CspNonceSource.REQUEST) {
+            LOG.debug("Reading nonce value from request attribute");
+            nonceValue = readNonceFromRequest(request);
+        } else {
+            LOG.warn("Unknown nonce source: {}, reading nonce value from 
session", nonceSource);
+            nonceValue = readNonceFromSession(request);
+        }
+        return nonceValue;
+    }
+
+    private NonceValue readNonceFromSession(HttpServletRequest request) {
+        HttpSession session = request.getSession(false);
+        Object nonceValue = session != null ? session.getAttribute("nonce") : 
null;
+        if (nonceValue == null) {
+            LOG.debug("Session is not active, cannot obtain nonce value");
+            return NonceValue.ofNullSession();
+        }
+        return NonceValue.ofSession(nonceValue.toString());
+    }
+
+    private NonceValue readNonceFromRequest(HttpServletRequest request) {
+        Object nonceValue = request.getAttribute("nonce");
+        if (nonceValue == null) {
+            LOG.warn("Request attribute 'nonce' is not set, cannot obtain 
nonce value");
+            return NonceValue.ofNullRequest();
+        }
+
+        return NonceValue.ofRequest(nonceValue.toString());
+    }
+}
diff --git a/core/src/main/resources/org/apache/struts2/default.properties 
b/core/src/main/resources/org/apache/struts2/default.properties
index 8b7226a89..7dd782ccb 100644
--- a/core/src/main/resources/org/apache/struts2/default.properties
+++ b/core/src/main/resources/org/apache/struts2/default.properties
@@ -280,4 +280,7 @@ struts.url.queryStringParser=strutsQueryStringParser
 struts.url.encoder=strutsUrlEncoder
 struts.url.decoder=strutsUrlDecoder
 
+### Defines source to read nonce value from, possible values are: request, 
session
+struts.csp.nonceSource=session
+
 ### END SNIPPET: complete_file
diff --git a/core/src/main/resources/struts-beans.xml 
b/core/src/main/resources/struts-beans.xml
index 5c3121f77..6aad85ca6 100644
--- a/core/src/main/resources/struts-beans.xml
+++ b/core/src/main/resources/struts-beans.xml
@@ -265,4 +265,7 @@
     <bean type="org.apache.struts2.interceptor.exec.ExecutorProvider" 
name="struts"
           class="org.apache.struts2.interceptor.exec.StrutsExecutorProvider"/>
 
+    <bean type="org.apache.struts2.interceptor.csp.CspNonceReader" 
name="struts"
+          class="org.apache.struts2.interceptor.csp.StrutsCspNonceReader"/>
+
 </struts>
diff --git a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java 
b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
index ff3dc50f1..1f20584f1 100644
--- a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
+++ b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
@@ -21,6 +21,8 @@ package org.apache.struts2.components;
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.config.ConfigurationException;
 import com.opensymphony.xwork2.util.ValueStack;
+import net.bytebuddy.implementation.InvokeDynamic;
+import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsInternalTestCase;
 import org.apache.struts2.components.template.Template;
 import org.apache.struts2.components.template.TemplateEngine;
@@ -32,6 +34,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockHttpSession;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import static 
com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsCheckerTest.NO_EXCLUSION_ACCEPT_ALL_PATTERNS_CHECKER;
@@ -236,6 +239,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.setAccesskey(accesskeyValue);
         txtFld.evaluateParams();
 
@@ -250,6 +255,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.addParameter("value", value);
         txtFld.evaluateParams();
 
@@ -338,6 +345,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.setCssClass(cssClass);
         txtFld.evaluateParams();
 
@@ -352,6 +361,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         ActionContext.getContext().withServletRequest(req);
 
         TextField txtFld = new TextField(stack, req, res);
+        container.inject(txtFld);
+
         txtFld.setStyle(cssStyle);
         txtFld.evaluateParams();
 
@@ -372,6 +383,8 @@ public class UIBeanTest extends StrutsInternalTestCase {
         actionContext.withSession(new SessionMap(req));
 
         DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
+        container.inject(dblSelect);
+
         dblSelect.evaluateParams();
 
         assertEquals(nonceVal, dblSelect.getAttributes().get("nonce"));
@@ -392,11 +405,35 @@ public class UIBeanTest extends StrutsInternalTestCase {
         session.invalidate();
 
         DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
+        container.inject(dblSelect);
+
         dblSelect.evaluateParams();
 
         assertNull(dblSelect.getAttributes().get("nonce"));
     }
 
+    public void testNonceOfRequestAttribute() {
+        Map<String, String> params = new HashMap<String, String>(){{
+            put(StrutsConstants.STRUTS_CSP_NONCE_SOURCE, "request");
+        }};
+        initDispatcher(params);
+
+        String nonceVal = "r4nd0m";
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        req.setAttribute("nonce", nonceVal);
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        ActionContext actionContext = stack.getActionContext();
+        actionContext.withServletRequest(req);
+
+        DoubleSelect dblSelect = new DoubleSelect(stack, req, res);
+        container.inject(dblSelect);
+
+        dblSelect.evaluateParams();
+
+        assertEquals(nonceVal, dblSelect.getAttributes().get("nonce"));
+    }
+
     public void testSetNullUiStaticContentPath() {
         // given
         ValueStack stack = ActionContext.getContext().getValueStack();
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
index 192e5a481..9129f24bc 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionErrorTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.components.ActionError;
 import org.apache.struts2.components.Anchor;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -72,6 +74,7 @@ public class ActionErrorTest extends AbstractTest {
         //errors are needed to setup stack
         super.setUp();
         this.tag = new ActionError(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
index bd550819f..8d8895372 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ActionMessageTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.ActionError;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -72,6 +74,7 @@ public class ActionMessageTest extends AbstractTest {
         //errors are needed to setup stack
         super.setUp();
         this.tag = new ActionError(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
index 2ac3b38d6..d7b1de8aa 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/AnchorTest.java
@@ -24,6 +24,8 @@ import 
com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsChecke
 import org.apache.struts2.components.Anchor;
 import org.apache.struts2.components.UIBean;
 import org.apache.struts2.components.ServletUrlRenderer;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class AnchorTest extends AbstractTest {
     private Anchor tag;
@@ -111,6 +113,7 @@ public class AnchorTest extends AbstractTest {
         this.tag = new Anchor(stack, request, response);
         this.tag.setUrlRenderer(new ServletUrlRenderer());
         this.tag.setNotExcludedAcceptedPatterns(new 
DefaultNotExcludedAcceptedPatternsChecker());
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
index a7060130f..d729703e1 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/CheckboxTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import 
com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsChecker;
 import org.apache.struts2.components.Checkbox;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class CheckboxTest extends AbstractCommonAttributesTest {
     private Checkbox tag;
@@ -88,6 +90,7 @@ public class CheckboxTest extends 
AbstractCommonAttributesTest {
         super.setUp();
         tag = new Checkbox(stack, request, response);
         tag.setNotExcludedAcceptedPatterns(new 
DefaultNotExcludedAcceptedPatternsChecker());
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
index 67d9dc5a5..7b1d36069 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/DateTextFieldTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.DateTextField;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class DateTextFieldTest extends AbstractCommonAttributesTest {
 
@@ -56,6 +58,7 @@ public class DateTextFieldTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new DateTextField(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
index fe35a58a0..fca239293 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FieldErrorTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.FieldError;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.*;
 
@@ -100,6 +102,7 @@ public class FieldErrorTest extends AbstractTest {
         //errors are needed to setup stack
         super.setUp();
         this.tag = new FieldError(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
index bf9786f3a..dce590b30 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FileTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.File;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class FileTest extends AbstractCommonAttributesTest {
     private File tag;
@@ -50,6 +52,7 @@ public class FileTest extends AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new File(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
index 34d176962..9ee9c9152 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/FormTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import org.apache.struts2.components.Form;
 import org.apache.struts2.components.UIBean;
 import org.apache.struts2.components.UrlRenderer;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 import org.easymock.EasyMock;
 
 public class FormTest extends AbstractCommonAttributesTest {
@@ -80,5 +82,6 @@ public class FormTest extends AbstractCommonAttributesTest {
         UrlRenderer renderer = EasyMock.createNiceMock(UrlRenderer.class);
         EasyMock.replay(renderer);
         tag.setUrlRenderer(renderer);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
index a1c276280..ace29fdbc 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HeadTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Head;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class HeadTest extends AbstractTest {
     private Head tag;
@@ -39,6 +41,7 @@ public class HeadTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Head(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
index 8884aaca0..c517a62e8 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/HiddenTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Hidden;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class HiddenTest extends AbstractTest {
     private Hidden tag;
@@ -49,6 +51,7 @@ public class HiddenTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Hidden(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
index 0dfbb81ad..90cda064c 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LabelTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Label;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class LabelTest extends AbstractCommonAttributesTest {
     private Label tag;
@@ -48,6 +50,7 @@ public class LabelTest extends AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Label(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
index 1fe7f0106..69c1a11bb 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/LinkTest.java
@@ -20,6 +20,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Link;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class LinkTest extends AbstractTest {
 
@@ -103,5 +105,6 @@ public class LinkTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Link(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
index a17e0fdce..ca12ff316 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/PasswordTest.java
@@ -22,15 +22,14 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Password;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class PasswordTest extends AbstractCommonAttributesTest {
 
     private Password tag;
 
     public void testRenderPassword() throws Exception {
-        super.setUp();
-        this.tag = new Password(stack, request, response);
-
         tag.setName("name");
         tag.setValue("val1");
         tag.setSize("10");
@@ -51,9 +50,6 @@ public class PasswordTest extends 
AbstractCommonAttributesTest {
     }
 
     public void testRenderPasswordShowIt() throws Exception {
-        super.setUp();
-        this.tag = new Password(stack, request, response);
-
         tag.setName("name");
         tag.setValue("val1");
         tag.setSize("10");
@@ -75,7 +71,9 @@ public class PasswordTest extends 
AbstractCommonAttributesTest {
 
     @Override
     protected void setUp() throws Exception {
-        //dont call base setup
+        super.setUp();
+        this.tag = new Password(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
@@ -85,8 +83,6 @@ public class PasswordTest extends 
AbstractCommonAttributesTest {
 
     @Override
     protected UIBean getUIBean() throws Exception {
-        super.setUp();
-        this.tag = new Password(stack, request, response);
         return tag;
     }
 
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
index 9695e884f..14464145f 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ResetTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Reset;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class ResetTest extends AbstractCommonAttributesTest {
     private Reset tag;
@@ -69,6 +71,7 @@ public class ResetTest extends AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Reset(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
index c0d93a629..6e51f8a44 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/ScriptTest.java
@@ -21,6 +21,8 @@ package org.apache.struts2.views.java.simple;
 import 
com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsChecker;
 import org.apache.struts2.components.Script;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 
 public class ScriptTest extends AbstractTest {
@@ -72,5 +74,6 @@ public class ScriptTest extends AbstractTest {
 
         this.tag = new Script(stack, request, response);
         tag.setNotExcludedAcceptedPatterns(new 
DefaultNotExcludedAcceptedPatternsChecker());
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 }
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
index 4fa2a6ed7..441d4e152 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SelectTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Select;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -114,6 +116,7 @@ public class SelectTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Select(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
index 84f45c2d8..4760bcc5c 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/SubmitTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.Submit;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class SubmitTest extends AbstractCommonAttributesTest {
     private Submit tag;
@@ -154,6 +156,7 @@ public class SubmitTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Submit(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
index d72f42bcb..08d08caba 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextAreaTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.TextArea;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class TextAreaTest extends AbstractCommonAttributesTest {
     private TextArea tag;
@@ -71,6 +73,7 @@ public class TextAreaTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new TextArea(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
index 212a991cc..331442f13 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TextFieldTest.java
@@ -22,6 +22,8 @@ package org.apache.struts2.views.java.simple;
 
 import org.apache.struts2.components.TextField;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 public class TextFieldTest extends AbstractCommonAttributesTest {
     private TextField tag;
@@ -52,6 +54,7 @@ public class TextFieldTest extends 
AbstractCommonAttributesTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new TextField(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
     }
 
     @Override
diff --git 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
index 7f7b3fbef..c667e8b9f 100644
--- 
a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
+++ 
b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
@@ -23,6 +23,8 @@ package org.apache.struts2.views.java.simple;
 import com.opensymphony.xwork2.ActionContext;
 import org.apache.struts2.components.Token;
 import org.apache.struts2.components.UIBean;
+import org.apache.struts2.interceptor.csp.CspNonceSource;
+import org.apache.struts2.interceptor.csp.StrutsCspNonceReader;
 
 import java.util.HashMap;
 import java.util.regex.Pattern;
@@ -49,6 +51,7 @@ public class TokenTest extends AbstractTest {
     protected void setUp() throws Exception {
         super.setUp();
         this.tag = new Token(stack, request, response);
+        this.tag.setCspNonceReader(new 
StrutsCspNonceReader(CspNonceSource.SESSION.name()));
 
         ActionContext.of()
             .withSession(new HashMap<>())

Reply via email to