@@ -287,6 +287,16 @@ def set_default_headers(self):
287
287
origin = self .get_origin ()
288
288
if origin and self .allow_origin_pat .match (origin ):
289
289
self .set_header ("Access-Control-Allow-Origin" , origin )
290
+ elif (
291
+ self .token_authenticated
292
+ and "Access-Control-Allow-Origin" not in
293
+ self .settings .get ('headers' , {})
294
+ ):
295
+ # allow token-authenticated requests cross-origin by default.
296
+ # only apply this exception if allow-origin has not been specified.
297
+ self .set_header ('Access-Control-Allow-Origin' ,
298
+ self .request .headers .get ('Origin' , '' ))
299
+
290
300
if self .allow_credentials :
291
301
self .set_header ("Access-Control-Allow-Credentials" , 'true' )
292
302
@@ -523,6 +533,28 @@ def options(self, *args, **kwargs):
523
533
self .set_header ('Access-Control-Allow-Methods' ,
524
534
'GET, PUT, POST, PATCH, DELETE, OPTIONS' )
525
535
536
+ # if authorization header is requested,
537
+ # that means the request is token-authenticated.
538
+ # avoid browser-side rejection of the preflight request.
539
+ # only allow this exception if allow_origin has not been specified
540
+ # and notebook authentication is enabled.
541
+ # If the token is not valid, the 'real' request will still be rejected.
542
+ requested_headers = self .request .headers .get ('Access-Control-Request-Headers' , '' ).split (',' )
543
+ if requested_headers and any (
544
+ h .strip ().lower () == 'authorization'
545
+ for h in requested_headers
546
+ ) and (
547
+ # FIXME: it would be even better to check specifically for token-auth,
548
+ # but there is currently no API for this.
549
+ self .login_available
550
+ ) and (
551
+ self .allow_origin
552
+ or self .allow_origin_pat
553
+ or 'Access-Control-Allow-Origin' in self .settings .get ('headers' , {})
554
+ ):
555
+ self .set_header ('Access-Control-Allow-Origin' ,
556
+ self .request .headers .get ('Origin' , '' ))
557
+
526
558
527
559
class Template404 (IPythonHandler ):
528
560
"""Render our 404 template"""
0 commit comments