Isaac.

API Authentication: OAuth 2.0

Understand OAuth 2.0: secure delegation of access without sharing passwords.

By EMEPublished: February 20, 2025
oauth2authenticationapi securityauthorizationtokens

A Simple Analogy

OAuth 2.0 is like valet parking. You don't give the valet your house key (password); you give them a limited valet key that only starts the car. They can't access your trunk or glove box. The valet key can be revoked without changing your house key.


What Is OAuth 2.0?

OAuth 2.0 is an authorization standard that allows users to grant third-party applications access to their resources without sharing passwords. It uses tokens instead of credentials.


Why Use OAuth 2.0?

  • Security: Users never share passwords with apps
  • Limited access: Grant specific permissions (scopes)
  • Revocable: Easily disable access without changing password
  • Delegation: Users authorize on identity provider
  • Industry standard: Works with Google, GitHub, Microsoft

OAuth 2.0 Flow (Authorization Code)

1. User: "Log in with Google"
2. App: Redirects to Google login
3. Google: User authenticates and approves permissions
4. Google: Redirects back with authorization code
5. App backend: Exchanges code for access token
6. App: Uses token to access user data

Key Concepts

| Term | Meaning | |------|---------| | Resource Owner | User who owns the data | | Client | Your application | | Authorization Server | Google, GitHub (issues tokens) | | Resource Server | API with user data | | Scope | Permission level (read, write) | | Token | Credential proving authorization |


.NET Implementation

// Install: Microsoft.AspNetCore.Authentication.OAuth

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "GitHub";
})
.AddCookie("Cookies")
.AddOAuth("GitHub", options =>
{
    options.ClientId = builder.Configuration["GitHub:ClientId"];
    options.ClientSecret = builder.Configuration["GitHub:ClientSecret"];
    options.CallbackPath = "/signin-github";
    
    options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
    options.TokenEndpoint = "https://github.com/login/oauth/access_token";
    options.UserInformationEndpoint = "https://api.github.com/user";
    
    options.ClaimActions.MapJsonKey("urn:github:login", "login");
    options.ClaimActions.MapJsonKey("urn:github:url", "html_url");
});

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();

[Authorize]
[Route("api/[controller]")]
public class ProfileController : ControllerBase
{
    [HttpGet]
    public IActionResult GetProfile()
    {
        var login = User.FindFirst("urn:github:login")?.Value;
        return Ok(new { github_login = login });
    }
}

Practical Example

// Using HttpClient to call API with OAuth token
public class GitHubService
{
    private readonly HttpClient _httpClient;
    private readonly IHttpContextAccessor _httpContextAccessor;
    
    public async Task<List<Repository>> GetUserRepositoriesAsync()
    {
        // Get token from authentication
        var token = await _httpContextAccessor.HttpContext
            .GetTokenAsync("access_token");
        
        _httpClient.DefaultRequestHeaders.Authorization =
            new("Bearer", token);
        
        var response = await _httpClient.GetAsync("https://api.github.com/user/repos");
        var json = await response.Content.ReadAsStringAsync();
        
        return JsonSerializer.Deserialize<List<Repository>>(json);
    }
}

Common Scopes

GitHub:
- repo: Access to repositories
- gist: Access to gists
- user: Access to user profile

Google:
- openid: Basic identity
- profile: User profile information
- email: User email address

Best Practices

  1. Use HTTPS: Always secure communication
  2. Validate tokens: Verify signature and expiration
  3. Scopes: Request minimal necessary permissions
  4. State parameter: Prevent CSRF attacks
  5. Refresh tokens: Rotate long-lived credentials

Related Concepts to Explore

  • OpenID Connect (built on OAuth 2.0)
  • PKCE (for mobile apps)
  • Token refresh strategies
  • Multiple OAuth providers
  • Custom authorization servers

Summary

OAuth 2.0 enables secure, delegated access without passwords. Use it for social login and API authentication to improve user experience and security.