I was able to do this by extending UsernamePasswordAuthenticationFilter… my code is in Groovy, hope that’s OK:
public class CorsAwareAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
static final String ORIGIN = 'Origin'
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){
if (request.getHeader(ORIGIN)) {
String origin = request.getHeader(ORIGIN)
response.addHeader('Access-Control-Allow-Origin', origin)
response.addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
response.addHeader('Access-Control-Allow-Credentials', 'true')
response.addHeader('Access-Control-Allow-Headers',
request.getHeader('Access-Control-Request-Headers'))
}
if (request.method == 'OPTIONS') {
response.writer.print('OK')
response.writer.flush()
return
}
return super.attemptAuthentication(request, response)
}
}
The important bits above:
- Only add CORS headers to response if CORS request detected
- Respond to pre-flight OPTIONS request with a simple non-empty 200 response, which also contains the CORS headers.
You need to declare this bean in your Spring configuration. There are many articles showing how to do this so I won’t copy that here.
In my own implementation I use an origin domain whitelist as I am allowing CORS for internal developer access only. The above is a simplified version of what I am doing so may need tweaking but this should give you the general idea.