I'm implementing the OpenId AppAuth SDK for IOS and Android.
https://github.com/openid/AppAuth-iOS
https://github.com/openid/AppAuth-android
Our app oAuth flow:
- In our app the user starts a oAuth login using the AppAuth SDK (IOS or Android).
- App retreives the authorisation code.
- The app sends the authorisation code to the backend server.
- The backend server creates the access token.
The app receives the following data from the backend server to perform the oAuth flow:
- authorization endpoint
- client_id
- response_type
- scope
Problem
The Android app works like a charm. A user can login using AppAuth and the app receives the authorization code from the redirectURL.
The IOS app however... AppAuth does open the requested login screen and can perform the oAuth login.
Then...
AppAuth dispatches an error in the callback from method:
[OIDAuthState authStateByPresentingAuthorizationRequest:presentingViewController:callback:]
The callback error:
"Connection error making token request to '': incorrect URL."`Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL`
The error is correct, because an empty NSURL is used as a token_endpoint in the ServiceConfiguration. The app does not have the token endpoint, ony the authorization endPoint.
It seems like AppAuth is automatically requesting the access token, but I only need to request the authorization code. The Android app also uses an empty url in the ServiceConfiguration, but does not start the token request.
How can I disable automatic token retreival, using AppAuth-iOS?
Android code (java):
private void startOAuthAuthentication(){
// Create the service coniguration
// Note: The app does not have a token endpoint. An empty Uri value is used for the tokenEndpoint param
AuthorizationServiceConfiguration serviceConfig =
new AuthorizationServiceConfiguration(
Uri.parse(MY_AUTHORISATION_ENDPOINT), // authorization_endpoint
Uri.parse("")); // token_endpoint
// Build the request
AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder(
serviceConfig,
MY_CLIENT_ID,
MY_RESPONSE_TYPE,
MY_REDIRECT_URL);
AuthorizationRequest authRequest = authRequestBuilder
.setScope(MY_SCOPE)
.setCodeVerifier(null)
.setLoginHint(null)
.build();
// Start Authorization
AuthorizationService authService = new AuthorizationService(getActivity());
Intent authIntent = authService.getAuthorizationRequestIntent(authRequest);
oAuthActivityResultLauncher.launch(authIntent);
}
// ActivityResultLauncher
ActivityResultLauncher<Intent> oAuthActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
AuthorizationResponse resp = AuthorizationResponse.fromIntent(data);
AuthorizationException ex = AuthorizationException.fromIntent(data);
if(resp != null && resp.authorizationCode != null){
// app received the authorizationCode
// resp.authorizationCode
}
}
}
});
IOS code (obj-c):
-(void) startOAuthAuthentication
{
// Create the service coniguration
// Note: The app does not have a token endpoint. An empty NSURL value is used for the tokenEndpoint param.
OIDServiceConfiguration *config =
[[OIDServiceConfiguration alloc]
initWithAuthorizationEndpoint:[NSURL URLWithString:MY_AUTHORISATION_ENDPOINT]
tokenEndpoint:[NSURL URLWithString:@""]];
// Create the Authorization Request
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc] initWithConfiguration:config
clientId:MY_CLIENT_ID
clientSecret:nil
scope:MY_SCOPE
redirectURL:MY_REDIRECT_URL
responseType:MY_RESPONSE_TYPE
state:MY_STATE
nonce:nil
codeVerifier:nil
codeChallenge:nil
codeChallengeMethod:nil
additionalParameters:nil];
// Start Authorization
AppDelegate *appDelegate =
(AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.currentAuthorizationFlow =
[OIDAuthState authStateByPresentingAuthorizationRequest:request
presentingViewController:self
callback:^(OIDAuthState *_Nullable authState,
NSError *_Nullable error) {
if (authState) {
// App does not receive the authState
} else {
// App always receives the following the error:
// "Connection error making token request to '': incorrect URL."
// Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL
}
}];
}