AppAuth-iOS icon indicating copy to clipboard operation
AppAuth-iOS copied to clipboard

Owner password flow using OIDTokenRequest crashes on token refresh

Open bryanrahn opened this issue 4 years ago • 2 comments

We support both Owner Password Flow, along with Authorization Code flow. I've wrapped our request layer with authState.performAction(freshTokens:). However, because I use OIDTokenRequest directly for the password flow, and call OIDAuthorizationService.perform(_: OIDTokenRequest, callback: OIDTokenCallback), AppAuth crashes in OIDTokenRequest.m on [bodyParameters addParameter:kClientIDKey value:_clientID]; since _clientID is nil.

Am I doing something wrong or not setting something I should be? Is password flow not officially supported?

Here's my password flow code snippet:

// Log in with username/pwd
OIDAuthorizationService.discoverConfiguration(forIssuer: issuer) { [weak self] configuration, error in
            guard let self = self, let config = configuration else {
                completion(.failure(AppAuthError.invalid))
                return
            }
            let request = OIDTokenRequest(configuration: config,
                                          grantType: OIDGrantTypePassword,
                                          authorizationCode: nil,
                                          redirectURL: redirectURL,
                                          clientID: clientID,
                                          clientSecret: nil,
                                          scope: OIDScopeOpenID,
                                          refreshToken: self.authState?.lastTokenResponse?.refreshToken,
                                          codeVerifier: nil,
                                          additionalParameters: ["username": username,
                                                                 "password": password])

            OIDAuthorizationService.perform(request) { [weak self] tokenResponse, error in
                guard let self = self else {
                    completion(.failure(AppAuthError.invalid))
                    return
                }

                if let tokenResponse = tokenResponse {
                    self.authState = OIDAuthState(authorizationResponse: nil,
                                                  tokenResponse: tokenResponse,
                                                  registrationResponse: nil)
               
                ...
                // continue on doing things

bryanrahn avatar Oct 02 '20 13:10 bryanrahn

Try to set redirectURL: nil and check. Also check your clientID should be non nil.

vijayradke avatar Nov 10 '20 06:11 vijayradke

Following up with my workaround on this:

OIDAuthorizationService.perform(request) { [weak self] tokenResponse, error in
    guard let self = self else {
        return
    }

    if let tokenResponse = tokenResponse {
        // Password flows using `OIDTokenRequest` don't ever produce an `OIDAuthorizationResponse`, so lets "fake" one
        // to prevent the `AppAuth` library from crashing when accessing a nil `client_id` query parameter when the
        // token expires and the library refreshes the token.
        let authResponse = OIDAuthorizationResponse(request: self.createAuthorizationRequest(with: config),
                                                    parameters: [String: NSCopying & NSObject]())
        self.authState = OIDAuthState(authorizationResponse: authResponse,
                                      tokenResponse: tokenResponse,
                                      registrationResponse: nil)
   } else {
      ...
   }

   ...
}

bryanrahn avatar Dec 17 '20 15:12 bryanrahn