TL;DR: It appears that pressing the "Approve" button on the .../scriptApproval/ WebUI has no effect until after Jenkins has been restarted.
I defined a pipeline build that contained the code:
final snapshotPropertiesReader = new java.io.StringReader(snapshotPropertiesAsString)
final snapshotProperties = new Properties()
discoHostedSnapshotName = snapshotProperties.getProperty('productUnderTest.SNAPSHOT')
First time I ran this pipeline code, I was using script security plugin version 1.39 and the pipeline code failed because "Scripts not permitted to use new java.util.Properties" (as one would expect). So I approved that method using the UI at http://myjenkinsserver/scriptApproval/.
However, the second time I ran it, despite having "approved" the code, the pipeline code failed with exactly the same error at the same point. Taking a look at the UI at http://myjenkinsserver/scriptApproval/ , I saw that "new java.util.Properties" was in the "Signatures already approved" list, but was also listed as needing approval. That shouldn't happen - a method can't be both "already approved" and in need of approval...
Pressing the "approve" button (again) made no difference to the list of "Signatures already approved" but did make the "pending approval" entry go away ... until I re-ran the build when it came back again.
Updating the plugin from 1.39 to 1.41 (and restarting Jenkins) initially appeared to fix the issue in that the build went on to the next line (where it's calling method java.util.Properties load java.io.Reader) ... but approving that had no effect on the build, only on the UI.
...until I restarted Jenkins, at which point I was able to progress to the next line (where it's calling method java.util.Properties getProperty java.lang.String).
i.e. It appears that signature "approval" only takes effect after a Jenkins restart.
At this point, I took screenshots - "scriptApprovalUI.png" shows that the method java.util.Properties getProperty java.lang.String is approved, but it also awaiting approval - the same method should never be in both places at once. "buildFailure.png" and "console_output.txt" show the build that failed (despite getProperty(String) being approved) and "pipeline.groovy" shows a (somewhat redacted) version of the pipeline code.