Skip to content

Commit

Permalink
Handle private network preflight call (#354)
Browse files Browse the repository at this point in the history
Chrome has a preflight check for local network requests that requires
our loopback listener to respond in a specific way in order to receive
the proper GET request.

Chrome document: https://developer.chrome.com/blog/private-network-access-preflight/

This document also says we need to include the
`Access-Control-Allow-Origin` header as well in order to succeed, but in
my (admittedly limited) tests that wasn't necessary. If it's deemed
prudent, I can add that to this PR as well.
  • Loading branch information
blairmitchelmore-okta authored Mar 21, 2024
1 parent 1c53317 commit ae54891
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions Sources/AppAuth/macOS/OKTRedirectHTTPHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,30 @@ - (void)stopHTTPListener {
}

- (void)HTTPConnection:(HTTPConnection *)conn didReceiveRequest:(HTTPServerRequest *)mess {
// Handle private network preflight
// https://developer.chrome.com/blog/private-network-access-preflight/
CFStringRef method = CFHTTPMessageCopyRequestMethod(mess.request);
BOOL isOptionsRequest = CFStringCompare(method, (__bridge CFStringRef)@"OPTIONS", 0) == kCFCompareEqualTo;

CFStringRef requestPrivateNetwork = isOptionsRequest ? CFHTTPMessageCopyHeaderFieldValue(mess.request, (__bridge CFStringRef)@"Access-Control-Request-Private-Network") : nil;
BOOL doesRequestPrivateNetwork = requestPrivateNetwork != nil && CFStringCompare(requestPrivateNetwork, (__bridge CFStringRef)@"true", 0) == kCFCompareEqualTo;
if (isOptionsRequest && doesRequestPrivateNetwork) {
CFHTTPMessageRef response = CFHTTPMessageCreateResponse(
kCFAllocatorDefault,
200,
NULL,
kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(response,
(__bridge CFStringRef)@"Access-Control-Allow-Private-Network",
(__bridge CFStringRef)@"true");
CFHTTPMessageSetHeaderFieldValue(response,
(__bridge CFStringRef)@"Content-Length",
(__bridge CFStringRef)@"0");
[mess setResponse:response];
CFRelease(response);
return;
}

// Sends URL to AppAuth.
CFURLRef url = CFHTTPMessageCopyRequestURL(mess.request);
BOOL handled = [_currentAuthorizationFlow resumeExternalUserAgentFlowWithURL:(__bridge NSURL *)url];
Expand Down

0 comments on commit ae54891

Please sign in to comment.