Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Sources/AppAuthCore/OIDAuthState.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,7 @@ static NSString *const kRefreshTokenRequestException =

/*! @brief Calls the block with a valid access token (refreshing it first, if needed), or if a
refresh was needed and failed, with the error that caused it to fail.
@param action The block to execute with a fresh token. This block will be executed on the main
thread.
@param action The block to execute with a fresh token.
@param additionalParameters Additional parameters for the token request if token is
refreshed.
@param dispatchQueue The dispatchQueue on which to dispatch the action block.
Expand All @@ -253,6 +252,17 @@ static NSString *const kRefreshTokenRequestException =
*/
- (void)setNeedsTokenRefresh;

/*! @brief The shared queue used for token refresh operations and delegate callbacks.
@discussion By default, all token refresh operations and delegate callbacks occur on
the main queue. Set this to a background queue if you need to call
@c OIDAuthState.performActionWithFreshTokens: synchronously without risking deadlock.
When using a custom queue, @c OIDAuthState should only be used from that queue, because it is not thread-safe.
Delelegate calls are dispatched from this queue as well.
This is a class-level property that affects all @c OIDAuthState instances.
The getter returns the main queue if no custom queue has been set.
*/
@property(class, nonatomic, strong, nullable) dispatch_queue_t sharedDelegateQueue;

/*! @brief Creates a token request suitable for refreshing an access token.
@return A @c OIDTokenRequest suitable for using a refresh token to obtain a new access token.
@discussion After performing the refresh, call @c OIDAuthState.updateWithTokenResponse:error:
Expand Down
10 changes: 10 additions & 0 deletions Sources/AppAuthCore/OIDAuthState.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ - (void)didChangeState;

@end

static dispatch_queue_t _sharedDelegateQueue = nil;

@implementation OIDAuthState {
/*! @brief Array of pending actions (use @c _pendingActionsSyncObject to synchronize access).
Expand Down Expand Up @@ -490,6 +491,14 @@ - (void)setNeedsTokenRefresh {
_needsTokenRefresh = YES;
}

+ (void)setSharedDelegateQueue:(dispatch_queue_t)queue {
_sharedDelegateQueue = queue;
}

+ (dispatch_queue_t)sharedDelegateQueue {
return _sharedDelegateQueue ?: dispatch_get_main_queue();
}

- (void)performActionWithFreshTokens:(OIDAuthStateAction)action {
[self performActionWithFreshTokens:action additionalRefreshParameters:nil];
}
Expand Down Expand Up @@ -547,6 +556,7 @@ - (void)performActionWithFreshTokens:(OIDAuthStateAction)action
[self tokenRefreshRequestWithAdditionalParameters:additionalParameters];
[OIDAuthorizationService performTokenRequest:tokenRefreshRequest
originalAuthorizationResponse:_lastAuthorizationResponse
callbackDispatchQueue:[OIDAuthState sharedDelegateQueue]
callback:^(OIDTokenResponse *_Nullable response,
NSError *_Nullable error) {
// update OIDAuthState based on response
Expand Down
6 changes: 6 additions & 0 deletions Sources/AppAuthCore/OIDAuthorizationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,14 @@ typedef void (^OIDRegistrationCompletion)(OIDRegistrationResponse *_Nullable reg
/*! @brief Performs a token request.
@param request The token request.
@param authorizationResponse The original authorization response related to this token request.
@param callbackDispatchQueue The dispatch queue on which to call the callback.
@param callback The method called when the request has completed or failed.
*/
+ (void)performTokenRequest:(OIDTokenRequest *)request
originalAuthorizationResponse:(OIDAuthorizationResponse *_Nullable)authorizationResponse
callbackDispatchQueue:(dispatch_queue_t)callbackDispatchQueue
callback:(OIDTokenCallback)callback;

+ (void)performTokenRequest:(OIDTokenRequest *)request
originalAuthorizationResponse:(OIDAuthorizationResponse *_Nullable)authorizationResponse
callback:(OIDTokenCallback)callback;
Expand Down
34 changes: 22 additions & 12 deletions Sources/AppAuthCore/OIDAuthorizationService.m
Original file line number Diff line number Diff line change
Expand Up @@ -423,11 +423,21 @@ + (void)discoverServiceConfigurationForDiscoveryURL:(NSURL *)discoveryURL
+ (void)performTokenRequest:(OIDTokenRequest *)request callback:(OIDTokenCallback)callback {
[[self class] performTokenRequest:request
originalAuthorizationResponse:nil
callbackDispatchQueue:dispatch_get_main_queue()
callback:callback];
}
+ (void)performTokenRequest:(OIDTokenRequest *)request
originalAuthorizationResponse:(OIDAuthorizationResponse *_Nullable)authorizationResponse
callback:(OIDTokenCallback)callback {
[self performTokenRequest:request
originalAuthorizationResponse:authorizationResponse
callbackDispatchQueue:dispatch_get_main_queue()
callback:callback];
}

+ (void)performTokenRequest:(OIDTokenRequest *)request
originalAuthorizationResponse:(OIDAuthorizationResponse *_Nullable)authorizationResponse
callbackDispatchQueue:(dispatch_queue_t)callbackDispatchQueue
callback:(OIDTokenCallback)callback {

NSURLRequest *URLRequest = [request URLRequest];
Expand All @@ -453,7 +463,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeNetworkError
underlyingError:error
description:errorDescription];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, returnedError);
});
return;
Expand Down Expand Up @@ -482,7 +492,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities OAuthErrorWithDomain:OIDOAuthTokenErrorDomain
OAuthResponse:json
underlyingError:serverError];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, oauthError);
});
return;
Expand All @@ -498,7 +508,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeServerError
underlyingError:serverError
description:errorDescription];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, returnedError);
});
return;
Expand All @@ -516,7 +526,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeJSONDeserializationError
underlyingError:jsonDeserializationError
description:errorDescription];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, returnedError);
});
return;
Expand All @@ -530,7 +540,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeTokenResponseConstructionError
underlyingError:jsonDeserializationError
description:@"Token response invalid."];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, returnedError);
});
return;
Expand All @@ -551,7 +561,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenParsingError
underlyingError:nil
description:@"ID Token parsing failed"];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, invalidIDToken);
});
return;
Expand All @@ -568,7 +578,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
underlyingError:nil
description:@"Issuer mismatch"];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, invalidIDToken);
});
return;
Expand All @@ -584,7 +594,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
underlyingError:nil
description:@"Audience mismatch"];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, invalidIDToken);
});
return;
Expand All @@ -610,7 +620,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
underlyingError:nil
description:@"ID Token expired"];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, invalidIDToken);
});
return;
Expand All @@ -628,7 +638,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
underlyingError:nil
description:message];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, invalidIDToken);
});
return;
Expand All @@ -644,7 +654,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
[OIDErrorUtilities errorWithCode:OIDErrorCodeIDTokenFailedValidationError
underlyingError:nil
description:@"Nonce mismatch"];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(nil, invalidIDToken);
});
return;
Expand All @@ -659,7 +669,7 @@ + (void)performTokenRequest:(OIDTokenRequest *)request
}

// Success
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(callbackDispatchQueue, ^{
callback(tokenResponse, nil);
});
}] resume];
Expand Down