Skip to content

OAuth2 Resource Owner Password Grant — Direct Credential Authentication

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about OAuth2 Resource Owner Password Grant. We cover key concepts, practical examples, and best practices to help you master this topic.

The OAuth2 Resource Owner Password Credentials (ROPC) grant allows a client to exchange a user's username and password directly for an access token.

What You'll Learn

How ROPC works, when it is appropriate (very few cases), security risks, and why it is being deprecated in favor of the Authorization Code grant with PKCE.

Why It Matters

ROPC is the most controversial OAuth2 grant. It requires the client to handle user passwords directly — the exact problem OAuth2 was designed to avoid. Understanding ROPC helps you recognize when you should NOT use it and why alternatives are better.

Real-World Use

ROPC is sometimes used for first-party applications (the company that owns the API also owns the app) where the user trusts the application implicitly. However, even this use case is being deprecated.

flowchart LR
    A["User"] -->|"Username + Password"| B["Client App"]
    B -->|"POST /token\ngrant_type=password"| C["Auth Server"]
    C -->|"Access Token + Refresh Token"| B
    B -->|"API call + Bearer token"| D["Resource Server"]
    D -->|"Data"| B
    B -->|"Shows data"| A
    style A fill:#dbeafe,stroke:#2563eb
    style B fill:#fecaca,stroke:#dc2626
    style C fill:#fef3c7,stroke:#d97706
    style D fill:#dcfce7,stroke:#16a34a

Code Example: ROPC Implementation

import requests

TOKEN_URL = "https://auth.example.com/oauth/token"
API_URL = "https://api.example.com/user/profile"
CLIENT_ID = "trusted-app"

# Step 1: Exchange username/password for token
response = requests.post(TOKEN_URL, data={
    "grant_type": "password",
    "username": "user@example.com",
    "password": "user-password",
    "client_id": CLIENT_ID,
    "scope": "profile"
})

token_data = response.json()
access_token = token_data["access_token"]
refresh_token = token_data.get("refresh_token")
print(f"Access token: {access_token[:20]}...")

# Step 2: Use token
headers = {"Authorization": f"Bearer {access_token}"}
profile = requests.get(API_URL, headers=headers)
print(profile.json())

Why ROPC Is Dangerous

Risk Description
Password Exposure The client application handles plain-text passwords
No Granular Consent The user cannot grant specific scopes — it is all or nothing
Credential Reuse Users often reuse passwords across services
No MFA Support Password grant cannot handle multi-factor authentication
Deprecated OAuth2 Security BCP recommends against it; many providers reject it

Code Example: Why Password Grant Fails with MFA

# Attempting password grant when MFA is enabled
response = requests.post(TOKEN_URL, data={
    "grant_type": "password",
    "username": "user@example.com",
    "password": "user-password",
    "client_id": CLIENT_ID
})

# Response when MFA is required
print(response.status_code)  # 400
print(response.json())
# {"error": "invalid_grant", "error_description": "MFA required"}

The password grant cannot handle MFA challenges. The Authorization Code grant with redirect-based authentication supports MFA naturally.

Common Mistakes

1. Using Password Grant for Third-Party Apps

Third-party apps should never see the user's password. Use Authorization Code grant to keep passwords between the user and the authorization server.

2. Not Handling MFA

Password grant fails when MFA is enabled. The error does not indicate whether the password was correct, creating a poor user experience.

3. Storing Passwords in the Client

The client should discard the password immediately after exchanging it for a token. Some apps store passwords for "convenience" — this is a security disaster.

4. Confusing Password Grant with Client Credentials

Password grant uses user credentials. Client Credentials uses application credentials. They serve different purposes.

5. Believing Password Grant Is Secure

Even with HTTPS, password grant exposes the password to the client application. A malicious or compromised client can capture the password.

Practice Questions

  1. What grant type uses username and password directly?
  2. Why is ROPC considered less secure than Authorization Code?
  3. What happens when a user has MFA enabled and uses password grant?
  4. Is ROPC appropriate for third-party applications?
  5. What is the recommended alternative to ROPC?

Answers:

  1. Resource Owner Password Credentials (ROPC) grant, with grant_type=password.
  2. The client handles plain-text passwords. Authorization Code keeps passwords between the user and the authorization server.
  3. The password grant fails because it cannot handle MFA challenges. The authorization server may return invalid_grant error.
  4. No. Third-party apps should never see user passwords. ROPC is only for highly trusted first-party applications.
  5. Authorization Code grant with PKCE provides the same user experience without exposing passwords to the client.

Challenge: Convert a password-grant authentication flow to Authorization Code with PKCE. Explain how this improves security and what the user experience differences are.

FAQ

Is ROPC completely deprecated?

The OAuth2 Security Best Current Practice recommends against ROPC. Major providers like Google and Microsoft no longer support it for new applications.

Can ROPC be used for testing?

Yes. For local development and testing, ROPC may be convenient. Never use it in production.

Does password grant support refresh tokens?

Yes. The authorization server may issue a refresh token along with the access token, allowing the client to maintain the session without re-entering the password.

What scopes can be requested with password grant?

The client requests scopes in the token request, but the user cannot selectively approve them. This is another security limitation.

How do you migrate from password grant to authorization code?

Change your app to redirect users to the authorization server's login page, receive the authorization code, and exchange it for tokens. User passwords never touch your app.

Mini Project

Write a Python script that demonstrates why password grant fails with MFA, then implement the same scenario using Authorization Code grant where MFA works naturally.

What's Next

Now learn the Authorization Code Grant — the most secure and widely recommended OAuth2 grant for web applications.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro