Skip to content

Make redirect_uri Optional for exchange_refresh_token Grant Type #1290

@ismailsaleekh

Description

@ismailsaleekh

Describe the problem

Feature Request: Make redirect_uri Optional for exchange_refresh_token Grant Type

Summary

Request to make the redirect_uri parameter optional for the exchange_refresh_token grant type on the ArcGIS OAuth 2.0 token endpoint, aligning with RFC 6749 standards and industry best practices.

Current Behavior

When using grant_type=exchange_refresh_token to obtain a new refresh token, the ArcGIS REST API requires the redirect_uri parameter:

From ArcGIS REST API Documentation:

Grant type Required parameters
exchange_refresh_token client_id, redirect_uri, refresh_token

Error when redirect_uri is omitted:

{
  "error": {
    "code": 400,
    "error": "invalid_request",
    "error_description": "redirect_uri not specified",
    "message": "redirect_uri not specified"
  }
}

Expected Behavior

The redirect_uri parameter should be optional for refresh token exchange operations, consistent with:

  1. RFC 6749 OAuth 2.0 specification
  2. The existing ArcGIS grant_type=refresh_token implementation
  3. Industry-standard OAuth 2.0 providers

RFC 6749 Compliance Analysis

Section 6: Refreshing an Access Token

RFC 6749 Section 6 defines the following parameters for refresh token operations:

Parameter Requirement Description
grant_type REQUIRED Value MUST be set to "refresh_token"
refresh_token REQUIRED The refresh token issued to the client
scope OPTIONAL The scope of the access request

Key observation: RFC 6749 does NOT require redirect_uri for refresh token operations.

The specification states:

"If the authorization server issued a refresh token to the client, the client makes a refresh request to the token endpoint by adding the following parameters..."

The redirect_uri is intentionally omitted from refresh operations because:

  1. No user redirection occurs during token refresh
  2. The refresh token itself cryptographically binds to the original authorization
  3. Client authentication (via client_id and optionally client_secret) provides sufficient identity verification

Section 4.1.3: When redirect_uri IS Required

RFC 6749 only requires redirect_uri during the initial authorization code exchange (Section 4.1.3):

"REQUIRED, if the redirect_uri parameter was included in the authorization request as described in Section 4.1.1, and their values MUST be identical."

This requirement exists to prevent authorization code injection attacks during the initial token exchange, not for subsequent refresh operations.

Industry Comparison

Providers that do NOT require redirect_uri for refresh token operations:

Provider Refresh Token Parameters Documentation
Google grant_type, client_id, client_secret, refresh_token Google OAuth 2.0
Microsoft/Azure AD grant_type, client_id, refresh_token, scope Microsoft Identity Platform
Auth0 grant_type, client_id, client_secret, refresh_token Auth0 Refresh Tokens
Okta grant_type, client_id, refresh_token, scope Okta Refresh Tokens

Google Actively Rejects redirect_uri in Refresh Requests

Google OAuth explicitly rejects requests that include redirect_uri in refresh token operations:

{
  "error": "invalid_request",
  "error_description": "Parameter not allowed for this message type: redirect_uri"
}

Reference: GitHub Issue oauth2-google#51

ArcGIS Already Implements RFC 6749-Compliant refresh_token Grant

Notably, ArcGIS's standard grant_type=refresh_token already follows RFC 6749 correctly:

Grant type Required parameters
refresh_token client_id, refresh_token

This inconsistency creates confusion: why does refresh_token not require redirect_uri, but exchange_refresh_token does?

Use Cases Impacted

1. Backend/Server Applications

Server-side applications that:

  • Store refresh tokens securely in databases
  • Implement automatic token rotation
  • Don't have user-facing redirect endpoints

These applications must artificially store and provide redirect_uri even though no redirection occurs.

2. Microservices and APIs

Distributed systems where:

  • Token management is centralized
  • Original authorization occurred on a different service
  • The refresh operation is decoupled from user interaction

3. Mobile and Desktop Applications

Native applications using:

  • Custom URL schemes (e.g., myapp://callback)
  • Loopback redirects (http://localhost:port)

These applications must persist the redirect URI alongside the refresh token, adding complexity.

4. Long-Running Background Processes

Automated systems that:

  • Run scheduled data synchronization
  • Perform batch operations on behalf of users
  • Require token refresh without user interaction

Security Considerations

Why redirect_uri Validation Doesn't Add Security for Refresh Operations

  1. No Redirection Occurs: The redirect_uri is not used for actual redirection during refresh operations—it's only used for validation.

  2. Refresh Token Binding: The refresh token is already cryptographically bound to:

    • The client application (client_id)
    • The user who authorized the application
    • The original scope granted
  3. Client Authentication: For confidential clients, client_secret or other authentication mechanisms provide identity verification.

  4. Token Theft Scenario: If an attacker obtains a refresh token:

    • They likely also have access to the stored redirect_uri
    • The redirect_uri check provides no additional protection
    • Proper countermeasures include token rotation and short expiration

RFC 6749 Security Guidance

Section 10.4 (Refresh Tokens) recommends:

"The authorization server MUST verify the binding between the refresh token and client identity whenever the client identity can be authenticated."

This is achieved through client_id verification, not redirect_uri validation.

Describe the proposed solution

Proposed Solution

Option A: Make redirect_uri Optional (Recommended)

Modify the exchange_refresh_token grant type to accept requests without redirect_uri:

Current:

POST /oauth2/token
grant_type=exchange_refresh_token
&client_id=xxx
&refresh_token=xxx
&redirect_uri=xxx  ← REQUIRED

Proposed:

POST /oauth2/token
grant_type=exchange_refresh_token
&client_id=xxx
&refresh_token=xxx
&redirect_uri=xxx  ← OPTIONAL (validated if provided)

Backward Compatibility

This change is fully backward compatible:

  • Existing applications that provide redirect_uri continue to work unchanged
  • The server can still validate redirect_uri when provided
  • New applications gain flexibility to omit it

Implementation Suggestion

// Pseudo-code for token endpoint handler
function handleExchangeRefreshToken(request) {
  const { client_id, refresh_token, redirect_uri } = request.body;
  
  // Validate required parameters
  if (!client_id || !refresh_token) {
    return error('invalid_request', 'Missing required parameters');
  }
  
  // Validate client
  const client = validateClient(client_id);
  
  // Validate refresh token binding
  const tokenData = validateRefreshToken(refresh_token, client_id);
  
  // OPTIONAL: Validate redirect_uri if provided
  if (redirect_uri) {
    if (redirect_uri !== tokenData.original_redirect_uri) {
      return error('invalid_grant', 'redirect_uri mismatch');
    }
  }
  
  // Issue new tokens
  return issueNewTokens(tokenData);
}

Documentation References

ArcGIS Documentation

OAuth 2.0 Standards

Environment

  • Endpoint: https://www.arcgis.com/sharing/rest/oauth2/token
  • Grant Type: exchange_refresh_token
  • Affected: All ArcGIS Online and ArcGIS Enterprise deployments

Summary

Aspect Current State Requested State
redirect_uri for exchange_refresh_token Required Optional
RFC 6749 Compliance Non-compliant Compliant
Industry Alignment Divergent Aligned
Backward Compatibility N/A Maintained

Thank you for considering this request. Making redirect_uri optional would:

  1. Align ArcGIS OAuth with RFC 6749 standards
  2. Match industry best practices (Google, Microsoft, Auth0, Okta)
  3. Simplify backend application development
  4. Maintain full backward compatibility

I'm happy to provide additional information or discuss implementation details.

Alternatives considered

No response

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions