we want to add the Content-Security-Policy header for our site ( Aem as Cloud) using dispatcher by adding the header in the site specific vhost file.
we added as below
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://example.com; style-src 'self' 'unsafe-inline'; font-src 'self' data:;"
but header is not visible as part of the response headers. it is not working
when we try using the cdn, through responseHeaderTransformer configuration.
but i want add through dispatcher only , why it is not working via dispatcher ?
please guide me to resolve the issue and make it work with dispatcher configuration .
<VirtualHost *:80>
ServerName "publish"
# Put names of which domains are used for your published site/content here
ServerAlias "*"
# Use a document root that matches the one in conf.dispatcher.d/default.farm
DocumentRoot "${DOCROOT}"
# URI dereferencing algorithm is applied at Sling's level, do not decode parameters here
AllowEncodedSlashes NoDecode
# Add header breadcrumbs for help in troubleshooting
SetEnvIfExpr "%{HTTP_HOST} == 'www.abc.com'" IS_WKKELOGG <IfModule mod_headers.c>
Header add X-Vhost "publish"
Header always set X-Vhost "wk-Vhost" ( this also not comming)
# Apply CSP for WK Kellogg
# Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://*.abc.com;" env=IS_WKKELOGG
# Apply CSP for Kashi
# Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://*.kashi.com;" env=IS_KASHI
################## Start of CORS configuration ##################
# Enable CORS handling in the dispatcher
#
# By default, CORS is handled by the AEM publish server.
# By adding the section below, CORS will be handled in the dispatcher.
# See the default.vhost file for a suggested dispatcher configuration. Note that:
# a. You will need to adapt the regex from default.vhost to match your CORS domains
# b. Remove the "Origin" header (if it exists) from the clientheaders.any file
# c. If you have any CORS domains configured in your AEM publish server origin, you have to move those to the dispatcher
# (i.e. accordingly update regex in default.vhost to match those domains)
#
SetEnvIfExpr "req_novary('Origin') == ''" CORSType=none CORSProcessing=false
SetEnvIfExpr "req_novary('Origin') != ''" CORSType=cors CORSProcessing=true CORSTrusted=false
SetEnvIfExpr "req_novary('Access-Control-Request-Method') == '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != ''" CORSType=invalidpreflight CORSProcessing=false
SetEnvIfExpr "req_novary('Access-Control-Request-Method') != '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != ''" CORSType=preflight CORSProcessing=true CORSTrusted=false
SetEnvIfExpr "req_novary('Origin') -strcmatch 'https://%{HTTP_HOST}*'" CORSType=samedomain CORSProcessing=false CORSTrusted=true
SetEnvIfExpr "req_novary('Origin') -strcmatch 'http://%{HTTP_HOST}*'" CORSType=samedomain CORSProcessing=false CORSTrusted=true
# For requests that require CORS processing, check if the Origin can be trusted
SetEnvIfExpr "%{HTTP_HOST} =~ /(.*)/ " ParsedHost=$1
################## BEGIN EDITABLE SECTION: Adapt regex to match CORS origin(s) for applications
################## The following provide access from common developer platforms, to accelerate AEM Headless access to WKND content.
# Developer Localhost
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(
http://localhost(:\d+)?$)#" CORSTrusted=true
# Adobe AppBuilder
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(
https://experience\.adobe\.com$)#" CORSTrusted=true
# Developer Vercel app
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.vercel\.app$)#" CORSTrusted=true
# Developer Github.io app
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.github\.io$)#" CORSTrusted=true
# Developer Codesandbox.io app
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*\.csb\.app$)#" CORSTrusted=true
# Developer CodePen.io app
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(
https://cdpn\.io$)#" CORSTrusted=true
# EDS site Dev and Prod sites
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*wkkellogg\.hlx\.live$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*wkkellogg\.aem\.live$)#" CORSTrusted=true
# WKKC EDS sites
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*wkkellogg\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*wkkellogg\.ca$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*ricekrispies\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*ricekrispies\.ca$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*frostedflakes\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*missiontiger\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*specialk\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*specialk\.ca$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*kashi\.com$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*kashi\.ca$)#" CORSTrusted=true
SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*wkkelloggawayfromhome\.com$)#" CORSTrusted=true
################## END EDITABLE SECTION
# Extract the Origin header
SetEnvIfNoCase ^Origin$ ^(.*)$ CORSTrustedOrigin=$1
# Flush If already set
Header unset Access-Control-Allow-Origin
Header unset Access-Control-Allow-Credentials
# Trusted
Header always set Access-Control-Allow-Credentials "true" "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Allow-Origin "%{CORSTrustedOrigin}e" "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Allow-Methods "GET" "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Max-Age 1800 "expr=reqenv('CORSTrusted') == 'true'"
Header always set Access-Control-Allow-Headers "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers" "expr=reqenv('CORSTrusted') == 'true'"
# Uncomment while debugging
# Header always set Debug-CORSProcessing "true" "expr=reqenv('CORSProcessing') == 'true'"
# Header always set Debug-CORSProcessing "false" "expr=reqenv('CORSProcessing') == 'false'"
# Header always set Debug-CORSTrusted "false" "expr=reqenv('CORSTrusted') == 'false'"
# Header always set Debug-CORSTrusted "true" "expr=reqenv('CORSTrusted') == 'true'"
# Non-CORS or Not Trusted
Header unset Access-Control-Allow-Credentials "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
Header unset Access-Control-Allow-Origin "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
Header unset Access-Control-Allow-Methods "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
Header unset Access-Control-Max-Age "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'"
# Always vary on origin, even if its not there.
Header merge Vary Origin
# CORS - send 204 for CORS requests which are not trusted
RewriteCond expr "reqenv('CORSProcessing') == 'true' && reqenv('CORSTrusted') == 'false'"
RewriteRule "^(.*)" - [R=204,L]
# Remove Origin before sending to AEM Publish
RequestHeader unset Origin
################## End of CORS configuration ##################
# Content Security Policies for wkkellogg.com
# Match specific domains
# SetEnvIfExpr "%{HTTP_HOST} == 'dev.wkkellogg.com' || %{HTTP_HOST} == 'www.wkkellogg.com'" is_wkkellogg
# Apply CSP header only for matched domains
</IfModule>
<Directory />
<IfModule disp_apache2.c>
# Some items cache with the wrong mime type
# Use this option to use the name to auto-detect mime types when cached improperly
ModMimeUsePathInfo On
# Use this option to avoid cache poisioning
# Sling will return /content/image.jpg as well as /content/image.jpg/ but apache can't search /content/image.jpg/ as a file
# Apache will treat that like a directory. This assures the last slash is never stored in cache
DirectorySlash Off
# Enable the dispatcher file handler for apache to fetch files from AEM
SetHandler dispatcher-handler
</IfModule>
Options FollowSymLinks
AllowOverride None
# Insert filter
SetOutputFilter DEFLATE
# Don't compress images
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
# Prevent clickjacking
Header always append X-Frame-Options SAMEORIGIN
</Directory>
<Directory "${DOCROOT}">
AllowOverride None
Require all granted
</Directory>
<IfModule disp_apache2.c>
# Enabled to allow rewrites to take affect and not be ignored by the dispatcher module
DispatcherUseProcessedURL On
# Default setting to allow all errors to come from the aem instance
DispatcherPassError 0
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
Include conf.d/rewrites/rewrite.rules
# Rewrite index page internally, pass through (PT)
RewriteRule "^(/?)$" "/index.html" [PT]
</IfModule>
# Removing Content-Disposition to make the robots.txt render instead of downloading in browser
<Location "/content/dam/wkkellogg/robots.txt">
Header unset Content-Disposition
</Location>
</VirtualHost>
@VeenaVi
Thanks and Regards,
Prashanth M