2

I built a AppAuth test app for android using an Azure AD tenant and it works ok. Now I am trying to the same with iOS (Swift 4) and failing when trying to exchange an access code for access token. No error is returned, I do get an idToken but no accessToken or refreshToken. No other errors. Not sure what is going on. Without an access token I can't query the graph. I am using Azure AD v2. Here are some pieces of my code:

func appAuthAuthorize(authConfig: AuthConfig) {
    let serviceConfiguration = OIDServiceConfiguration(
        authorizationEndpoint: NSURL(string: authConfig.authEndPoint)! as URL,
        tokenEndpoint: NSURL(string: authConfig.tokenEndPoint)! as URL)

    let request = OIDAuthorizationRequest(configuration: serviceConfiguration, clientId: authConfig.clientId, scopes: [OIDScopeOpenID, OIDScopeProfile], redirectURL: NSURL(string: authConfig.redirectUri)! as URL, responseType: OIDResponseTypeCode, additionalParameters: nil)

    doAppAuthAuthorization(authRequest: request)
}


func doAppAuthAuthorization(authRequest: OIDAuthorizationRequest) {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    appDelegate.currentAuthorizationFlow = OIDAuthorizationService.present(authRequest, presenting: self, callback: {
        (authorizationResponse, error) in
        if (authorizationResponse != nil) {
            self.authState = OIDAuthState(authorizationResponse: authorizationResponse!)
            self.logMessage(message: "Got authorization code: \(String(describing: self.authState?.lastAuthorizationResponse.authorizationCode))")
            self.doTokenRequest()
        } else {
            self.authState = nil
            self.logMessage(message: "Authorization error: \(String(describing: error?.localizedDescription))")
        }
    })
}

func doTokenRequest() {
    let tokenExchangeRequest = authState?.lastAuthorizationResponse.tokenExchangeRequest()

    OIDAuthorizationService.perform(tokenExchangeRequest!) {
        tokenResponse, error in
        if tokenResponse == nil{
            self.logMessage(message: "Token exchange error: \(error!.localizedDescription)")
        } else {
            self.authState?.update(with: tokenResponse!, error: error)
            self.saveState()
            self.logMessage(message: "Received token response with accesToken: \(tokenResponse!.idToken!)")
            self.logMessage(message: "Received token response with accesToken: \(tokenResponse!.refreshToken!)")
            self.logMessage(message: "Received token response with accesToken: \(tokenResponse!.accessToken!)")
            self.retrieveUserProfile()
        }

        self.authState?.update(with: tokenResponse, error: error)
    }
}
Igor
  • 569
  • 5
  • 24
  • Have you registered the application to the graph api using PowerShell? I have to do this with v1.6, but I'm not sure it is need with v2. – Pytry Sep 11 '17 at 18:51
  • Don't have to do it. My Android app and an iOS example using MSAL work ok. Its only AppAuth that's not working correctly. – Igor Sep 11 '17 at 18:58
  • Ah, ok. I could maybe provide an OpenIdConnect restful flow, but I've never used MSAL. Sorry. – Pytry Sep 11 '17 at 19:08
  • Well I am using the AppAuth Google library for iOS (https://github.com/openid/AppAuth-iOS) and as stated before, when trying to acquire a token from Azure AD, I am failing. – Igor Sep 11 '17 at 19:40

1 Answers1

1

Got the answer. The problem is that depending on the authorization server, one has to use scopes defined for that server. In the code above, I used the default OpenId scopes of OIDScopeOpenID and OIDScopeProfile. As soon as I changed this to Azure AD scope of User.Read, everything started working correctly. So here is the net change to the code in function appAuthAuthorize:

func appAuthAuthorize(authConfig: AuthConfig) {
let serviceConfiguration = OIDServiceConfiguration(
    authorizationEndpoint: NSURL(string: authConfig.authEndPoint)! as URL,
    tokenEndpoint: NSURL(string: authConfig.tokenEndPoint)! as URL)

let request = OIDAuthorizationRequest(configuration: serviceConfiguration, clientId: authConfig.clientId, scopes: ["User.Read"], redirectURL: NSURL(string: authConfig.redirectUri)! as URL, responseType: OIDResponseTypeCode, additionalParameters: nil)

doAppAuthAuthorization(authRequest: request)

}

Igor
  • 569
  • 5
  • 24
  • I'm getting ""Token exchange error: The operation couldn’t be completed. OAuth error: invalid_grant" , did you faced any similar issue? – Jan Sep 28 '17 at 06:12