1
votes

Previously asked this question in the Salesforce StackExchange which they considered off-topic so asking here to see if I can get an answer.


Background

I am attempting to use the immediate parameter to check if a Salesforce user has already approved access when going through the Web Server OAuth Flow as documented on OAuth 2.0 Web Server Authentication Flow. My reasoning for this is that I do not want the login or consent prompts to appear so I can reject access if they have not already approved.

Once the callback page is hit, I am always receiving the parameter error=immediate_unsuccessful even if the user has approved the application before and is logged in.

I have attempted to check this via a customised Google OAuth 2 Playground and setting immediate=true or immediate=false to the end of the authorize endpoint. On =false, the consent prompt shows and then you can grant access. On =true, this returns the same error as listed previously.

The Connected App that has been set up has api and refresh_token as the available scopes, users are able to authorize themselves and there are no ip restrictions set. The client id and secret from this app is then passed into the OAuth 2 Playground.

Below is a brief example on how my proper application redirects to the auth url using Java and the Google OAuth client library. We initially authorize the client without the immediate and then later on call the same code with immediate=true (shown in example)

AuthorizationCodeFlow authorizationCodeFlow = new AuthorizationCodeFlow.Builder(BearerToken.authorizationHeaderAccessMethod(), 
            httpTransport, 
            GsonFactory.getDefaultInstance(), 
            new GenericUrl("https://login.salesforce.com/services/oauth2/token"),
            new ClientParametersAuthentication(CLIENT_ID, CLIENT_SECRET), 
            CLIENT_ID,
            "https://login.salesforce.com/services/oauth2/authorize")
            .setCredentialDataStore(StoredCredential.getDefaultDataStore(MemoryDataStoreFactory.getDefaultInstance()))
            .build();

    AuthorizationCodeRequestUrl authUrl = authorizationCodeFlow.newAuthorizationUrl()
        .setRedirectUri("https://72hrn138.ngrok.io/oauth/callback")
        .setScopes(ImmutableSet.<String> of("api", "refresh_token"))
        .set("prompt", "consent")
        .set("immediate", "true");

    response.redirect(authUrl);

Question(s)

  • Are there any settings that I may have missed in Salesforce that would alleviate the error?
  • Is there any other option in the OAuth 2 spec that has to be set for the immediate option to work?
  • Does the immediate setting work?
1

1 Answers

1
votes

I managed to solve this issue in the end. To allow the immediate=true option to work, the scopes have to be removed from the request. In the example provided you would amend the authUrl to the following:

AuthorizationCodeRequestUrl authUrl = authorizationCodeFlow.newAuthorizationUrl()
    .setRedirectUri("https://72hrn138.ngrok.io/oauth/callback")
    .set("prompt", "consent")
    .set("immediate", "true");

I believe the theory is that defining a scope means you are asking for permissions to use those scope and therefore requires approval for those permissions. This clashes with the immediate option which states that the user must be logged in and the client id already been approved for it to succeed.