求助:如何为Grails 2.5应用配置Content-Security-Policy头
Configuring Content-Security-Policy for Grails 2.5 Apps
Since Grails 2.5 doesn’t include built-in support for Content-Security-Policy (CSP) headers, you’ll need to implement this manually. Below are two reliable, Grails-2.x-friendly approaches to get it working, plus key tips to avoid breaking your app:
Option 1: Use a Grails Interceptor (Native Grails Approach)
Grails interceptors let you hook into the request/response cycle cleanly. This is the most "Grails-native" way to inject CSP headers:
- Create a new interceptor file at
grails-app/interceptors/CspInterceptor.groovy:
class CspInterceptor { // Set high priority to ensure this runs before other interceptors int order = 0 CspInterceptor() { // Match all requests (adjust this if you need to exclude specific paths) matchAll() } boolean after() { true } void afterView() { // Customize these directives to match your app's resource needs String cspPolicy = """ default-src 'self'; script-src 'self' 'unsafe-inline'; // Allow inline scripts if your app relies on them (minimize if possible) style-src 'self' 'unsafe-inline'; // Same for inline styles img-src 'self' data:; // Allow base64-encoded images via data URIs frame-ancestors 'none'; // Modern replacement for X-Frame-Options: DENY """.replaceAll("\\s+", " ").trim() // Clean up extra whitespace response.setHeader("Content-Security-Policy", cspPolicy) } }
- Test it: Fire up your app, open your browser’s DevTools > Network tab, and verify the
Content-Security-Policyheader appears in response headers.
Option 2: Use a Servlet Filter (Lower-Level, Broader Coverage)
If you need to cover static assets or paths that interceptors might miss, a Servlet Filter is a more robust choice:
- Create a filter class (use Java or Groovy). For example,
src/java/com/yourcompany/CspFilter.java:
import javax.servlet.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CspFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; String cspPolicy = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none';"; httpResponse.setHeader("Content-Security-Policy", cspPolicy); chain.doFilter(request, response); } @Override public void destroy() {} }
- Register the filter in
grails-app/conf/web.xml:
Add these blocks inside the<web-app>tag (place them before other filters for priority):
<filter> <filter-name>CspFilter</filter-name> <filter-class>com.yourcompany.CspFilter</filter-class> </filter> <filter-mapping> <filter-name>CspFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Critical Tips for a Smooth Rollout
- Test with Report-Only mode first: To avoid breaking your app while tuning the policy, replace
Content-Security-PolicywithContent-Security-Policy-Report-Only. This logs violations to the browser console without blocking resources. - Tune directives for your app: If you use third-party tools (e.g., analytics, CDNs), add their domains to the relevant directives. For example, to allow Google Analytics, update
script-srcto'self' 'unsafe-inline' www.google-analytics.com;. - Keep X-Frame-Options as a fallback: While
frame-ancestors 'none'in CSP replacesX-Frame-Options: DENY, older browsers don’t support CSP. Keep your existing X-Frame-Options plugin enabled for backward compatibility.
内容的提问来源于stack exchange,提问作者dev-eloper
相关产品推荐
相关产品推荐

