Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOS Logout Crash : The service configuration is missing an end_session_endpoint. #806

Open
bydevelopertr opened this issue Nov 27, 2023 · 7 comments
Labels
bug triage Issues that need to be triaged

Comments

@bydevelopertr
Copy link

Hi Guys,

I crash while trying to logout :

*** Assertion failure in -[OIDEndSessionRequest endSessionRequestURL], OIDEndSessionRequest.m:184

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The service configuration is missing an end_session_endpoint.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000180437330 __exceptionPreprocess + 172
1 libobjc.A.dylib 0x0000000180051274 objc_exception_throw + 56
2 Foundation 0x0000000180ae29b4 _userInfoForFileAndLine + 0
3 ....

My Request:

let authorizationEndpoint = URL(string: Constants.ApiGa.authorizationEndpoint)!
let tokenEndpoint = URL(string: Constants.ApiGa.tokenEndpoint)!
let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint,
tokenEndpoint: tokenEndpoint)

    var redirectURL = redirectURL = Constants.OIDAuthorization.redirectURL
    var idToken = "" idToken = KeyChain.getKeychainValue(value: "my_idToken")
    
    let request = OIDEndSessionRequest(configuration: configuration,
                                                idTokenHint: idToken,
                                                postLogoutRedirectURL: URL(string: redirectURL)!,
                                                additionalParameters: nil)

Please Help :/

@bydevelopertr bydevelopertr added bug triage Issues that need to be triaged labels Nov 27, 2023
@fbaumgart
Copy link

Did you do endpoint setup by discovery? Or you declared endpoints manually?

@bydevelopertr
Copy link
Author

Did you do endpoint setup by discovery? Or you declared endpoints manually?

I didn't understand what you said. Have you logged out using this library before? If so, can you share sample code?

@fbaumgart
Copy link

fbaumgart commented Jan 9, 2024

The crash logs are quite explicit - you need to specify to end_session_endpoint in the configuration.
OIDServiceConfiguration contains this one and you probably didn't assign it.

@bydevelopertr
Copy link
Author

The crash logs are quite explicit - you need to specify to end_session_endpoint in the configuration. OIDServiceConfiguration contains this one and you probably didn't assign it.

Can you explain with example swift code?

@PiplaniVinay
Copy link

Hello Everyone,

I'm facing an issue with integrating Auth0 to log out of my iOS app using the AppAuth SDK. When using Keycloak, everything works fine because it provides an end_session_endpoint, but with Auth0, this endpoint is missing, leading to problems during logout.

I've tried implementing a fallback mechanism by constructing a custom logout URL, but although the app no longer crashes, the logout process still doesn't work correctly. Here's the code I'm using:

func logout(forCredential credential: AlfrescoCredential) {
guard let issuerURL = URL(string: configuration.host ?? "") else {
return
}

OIDAuthorizationService.discoverConfiguration(forIssuer: issuerURL) { [weak self] pkceConfiguration, error in
    guard let sSelf = self else { return }

    guard let viewController = sSelf.presentingViewController else {
        return
    }

    if error != nil {
        return
    }

    guard var pkceConfiguration = pkceConfiguration else {
        return
    }

    var customConfiguration = pkceConfiguration

    if pkceConfiguration.endSessionEndpoint == nil {
        // Fallback to Auth0's standard logout URL
        let logoutURLString = "\(sSelf.configuration.host ?? "")/v2/logout?client_id=\(sSelf.configuration.clientID)&returnTo=\(sSelf.configuration.redirectURI ?? "")"
        
        if let logoutURL = URL(string: logoutURLString) {
            customConfiguration = OIDServiceConfiguration(
                authorizationEndpoint: pkceConfiguration.authorizationEndpoint,
                tokenEndpoint: pkceConfiguration.tokenEndpoint,
                issuer: pkceConfiguration.issuer,
                registrationEndpoint: pkceConfiguration.registrationEndpoint,
                endSessionEndpoint: logoutURL
            )
        }
    }

    let logoutRequest = OIDEndSessionRequest(
        configuration: customConfiguration,
        idTokenHint: credential.idToken ?? "",
        postLogoutRedirectURL: URL(string: sSelf.configuration.redirectURI ?? "")!,
        state: (sSelf.authSession?.authState?.lastAuthorizationResponse.state) ?? "",
        additionalParameters: nil
    )

    sSelf.logoutUserAgent = OIDExternalUserAgentIOSSafari(presentingViewController: viewController)

    if let userAgent = sSelf.logoutUserAgent {
        sSelf.authSession?.authorizationFlow = OIDAuthorizationService.present(
            logoutRequest,
            externalUserAgent: userAgent,
            callback: { [weak self] (_, error) in
                guard let sSelf = self else { return }

                if let authError = error as NSError? {
                    sSelf.authDelegate?.didLogOut(result: .failure(APIError(domain: moduleName, code: authError.code, error: authError)))
                } else {
                    sSelf.authDelegate?.didLogOut(result: .success(StatusCodes.code200OK.code))
                }
            }
        )
    }
}

}

I would appreciate any insights or suggestions on how to make the logout process work correctly with Auth0, especially when the end_session_endpoint is not provided. Thank you!

@KarlBusse
Copy link

According to their docs they do have an end_session_endpoint.

@PiplaniVinay
Copy link

@KarlBusse Thanks I got the end_session_endpoint. But Logout is not working I am using the below code
func logout(forCredential credential: AlfrescoCredential) {

    guard let issuerURL = URL(string: configuration.host ?? "") else {
        self.authDelegate?.didReceive(result: .failure(nilIssuerError()))
        return
    }

    OIDAuthorizationService.discoverConfiguration(forIssuer: issuerURL) { [weak self] pkceConfiguration, error in
        guard let sSelf = self else { return }

        guard let viewController = sSelf.presentingViewController else {
            sSelf.authDelegate?.didReceive(result: .failure(sSelf.nilViewControllerError()))
            return
        }

        if let error = error as NSError? {
            sSelf.authDelegate?.didReceive(result: .failure(APIError(domain: moduleName,
                                                                     code: error.code,
                                                                     error: error)))
            return
        }
        guard let pkceConfiguration = pkceConfiguration else {
            sSelf.authDelegate?.didReceive(result: .failure(sSelf.nilIssuerError()))
            return
        }
        
        let logoutRequest =
            OIDEndSessionRequest(configuration: pkceConfiguration,
                                 idTokenHint: credential.idToken ?? "",
                                 postLogoutRedirectURL: URL(string: sSelf.configuration.redirectURI ?? "")!,
                                 state: (sSelf.authSession?.authState?.lastAuthorizationResponse.state) ?? "",
                                 additionalParameters: nil)

        sSelf.logoutUserAgent =
            OIDExternalUserAgentIOSSafari(presentingViewController: viewController)

        if let userAgent = sSelf.logoutUserAgent {
            sSelf.authSession?.authorizationFlow =
                OIDAuthorizationService.present(
                    logoutRequest,
                    externalUserAgent: userAgent,
                    callback: {[weak self] (_, error) in
                        guard let sSelf = self else { return }

                        if let authError = error as NSError? {
                            sSelf.authDelegate?.didLogOut(result: .failure(APIError(domain: moduleName,
                                                                                    code: authError.code,
                                                                                    error: authError )))
                        } else {
                            sSelf.authDelegate?.didLogOut(result: .success(StatusCodes.code200OK.code))
                        }
                    })
        }
    }
}

The same code is working fine in Keyclock.

The error is that Safari cannot open the page because the address is invalid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug triage Issues that need to be triaged
Projects
None yet
Development

No branches or pull requests

4 participants