Skip to content

Support per-request ResourceTransformer execution for index.html to enable CSP nonce injection #3264

Description

@kimtaa

Use case

We enforce a Content Security Policy with a per-request nonce (script-src 'nonce-{value}').
The nonce is generated fresh on every request and must be injected into the nonce attribute of
all <script> and <style> tags in index.html. We do this via a custom SwaggerIndexTransformer:

public class SwaggerNonceTransformer extends SwaggerIndexPageTransformer {                                                                  
    @Override   
    public Resource transform(HttpServletRequest request, Resource resource,
            ResourceTransformerChain chain) throws IOException {                                                                            
        Resource transformed = super.transform(request, resource, chain);
        if (resource.toString().contains("index.html")) {                                                                                   
            String html = new String(transformed.getInputStream().readAllBytes(), UTF_8);
            String nonce = request.getAttribute("cspNonce").toString();                                                                     
            html = html.replace("<script", "<script nonce='" + nonce + "'")
                       .replace("<style",  "<style nonce='" + nonce + "'");                                                                 
            return new TransformedResource(resource, html.getBytes());                                                                      
        }
        return transformed;                                                                                                                 
    }           
}

This worked correctly in springdoc 2.x, where all swagger-ui handlers used resourceChain(false)
and transformers ran on every request.

Problem

AbstractSwaggerConfigurer.getSwaggerHandlerConfigs() registers index.html with createCached(),
which causes SwaggerWebMvcConfigurer to use resourceChain(true, cache) for that handler.
This adds CachingResourceTransformer to the chain, which caches the transformer output after
the first request and never calls transform() again — making per-request transformation of
index.html impossible.

Interestingly, swagger-initializer.js is already served via createUncached() precisely
because it needs per-request transformer execution (for config injection). We need the same
capability for index.html.

Requested feature

Expose a way to opt out of CachingResourceTransformer for the index.html handler, for example:

  • A configuration property such as springdoc.swagger-ui.cache.transformer.disabled=true
  • Or making addSwaggerResourceHandler() check springdoc.swagger-ui.cache.disabled in addition to the existing springdoc.cache.disabled
    property

Activity

  1. added a commit that references this issue on Apr 25, 2026
    3676ab8
  2. limehee commented on Apr 26, 2026

    @limehee
    SponsorContributor

    I worked on a fix for this issue and opened draft PR #3279.

  3. added a commit that references this issue on Apr 26, 2026
    49b90bc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions