<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Esperanza Najera</title>
    <description>The latest articles on Forem by Esperanza Najera (@peranv).</description>
    <link>https://forem.com/peranv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F962428%2F2486afc2-597c-4ef5-aff7-5b2fa72d75ea.jpeg</url>
      <title>Forem: Esperanza Najera</title>
      <link>https://forem.com/peranv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/peranv"/>
    <language>en</language>
    <item>
      <title>🔐 How to Implement OAuth 2.0 Authentication in ASP.NET Core with External APIs</title>
      <dc:creator>Esperanza Najera</dc:creator>
      <pubDate>Mon, 11 Nov 2024 02:51:01 +0000</pubDate>
      <link>https://forem.com/peranv/how-to-implement-oauth-20-authentication-in-aspnet-core-with-external-apis-k7d</link>
      <guid>https://forem.com/peranv/how-to-implement-oauth-20-authentication-in-aspnet-core-with-external-apis-k7d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introducción&lt;/strong&gt;&lt;br&gt;
In today’s interconnected digital world, integrating with external APIs securely is more important than ever. One of the most widely used methods for securing API communication is OAuth 2.0. In this article, we'll walk through the process of implementing OAuth 2.0 authentication in an ASP.NET Core application, specifically for accessing an external API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We'll cover how to:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Obtain an access token using Client Credentials.&lt;br&gt;
Use that token to authenticate requests to a protected external API.&lt;br&gt;
Handle token expiration and errors effectively.&lt;br&gt;
By the end of this tutorial, you'll have a clear understanding of how to use OAuth 2.0 in your ASP.NET Core projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagram of the Authentication Flow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb6pe0zkbeiwqi3702xp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb6pe0zkbeiwqi3702xp.png" alt="Image description" width="800" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Client:&lt;/strong&gt; Initiates the flow by sending a POST request to the controller with the necessary data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controller:&lt;/strong&gt; Checks if a valid token is available. If not, it calls the service to obtain one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service:&lt;/strong&gt; Sends a request to the OAuth server to get a token using the client credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth Server:&lt;/strong&gt; Generates and returns an access token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controller:&lt;/strong&gt; Uses the token to send the data to the external API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External API:&lt;/strong&gt; Processes the request and returns a response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client:&lt;/strong&gt; Receives the final response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Before we start, make sure you have the following tools installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET 7 SDK or later&lt;/li&gt;
&lt;li&gt;Visual Studio or Visual Studio Code&lt;/li&gt;
&lt;li&gt;Postman for testing API requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Setting Up Your ASP.NET Core Project&lt;/strong&gt;&lt;br&gt;
Let's create a new ASP.NET Core Web API project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new webapi -n OAuthExample&lt;br&gt;
cd OAuthExample&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configuring appsettings.json&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "OAuthSettings": {
    "ClientId": "your_client_id",
    "ClientSecret": "your_client_secret",
    "TokenEndpoint": "https://oauth2.example.com/token",
    "GrantType": "client_credentials"
  },
  "ApiSettings": {
    "BaseUrl": "https://api.example.com/",
    "ProtectedEndpoint": "api/resource"
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Creating the Configuration Classes&lt;/strong&gt;&lt;br&gt;
Create two classes, OAuthSettings.cs and ApiSettings.cs, to map the configurations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OAuthSettings.cs&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class OAuthSettings
{
    public string ClientId { get; set; }
    public string ClientSecret { get; set; }
    public string TokenEndpoint { get; set; }
    public string GrantType { get; set; }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;ApiSettings.cs&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ApiSettings
{
    public string BaseUrl { get; set; }
    public string ProtectedEndpoint { get; set; }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Registering Services in Program.cs&lt;/strong&gt;&lt;br&gt;
Make sure you configure the services in Program.cs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure&amp;lt;OAuthSettings&amp;gt;(builder.Configuration.GetSection("OAuthSettings"));
builder.Services.Configure&amp;lt;ApiSettings&amp;gt;(builder.Configuration.GetSection("ApiSettings"));

builder.Services.AddHttpClient("ApiClient", client =&amp;gt;
{
    var apiSettings = builder.Configuration.GetSection("ApiSettings").Get&amp;lt;ApiSettings&amp;gt;();
    client.BaseAddress = new Uri(apiSettings.BaseUrl);
})
.ConfigurePrimaryHttpMessageHandler(() =&amp;gt; new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =&amp;gt; true
});

builder.Services.AddScoped&amp;lt;ApiService&amp;gt;();
builder.Services.AddControllers();

var app = builder.Build();
app.MapControllers();
app.Run();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Creating the ApiService&lt;/strong&gt;&lt;br&gt;
This service handles the process of obtaining the access token and making authenticated requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ApiService
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly OAuthSettings _oauthSettings;
    private readonly ApiSettings _apiSettings;

    public ApiService(IHttpClientFactory httpClientFactory, IOptions&amp;lt;OAuthSettings&amp;gt; oauthOptions, IOptions&amp;lt;ApiSettings&amp;gt; apiOptions)
    {
        _httpClientFactory = httpClientFactory;
        _oauthSettings = oauthOptions.Value;
        _apiSettings = apiOptions.Value;
    }

    public async Task&amp;lt;string?&amp;gt; GetAccessTokenAsync()
    {
        var client = _httpClientFactory.CreateClient("ApiClient");

        var authHeaderValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_oauthSettings.ClientId}:{_oauthSettings.ClientSecret}"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authHeaderValue);

        var formData = new Dictionary&amp;lt;string, string&amp;gt;
        {
            {"grant_type", _oauthSettings.GrantType}
        };

        var tokenResponse = await client.PostAsync(_oauthSettings.TokenEndpoint, new FormUrlEncodedContent(formData));
        var rawResponse = await tokenResponse.Content.ReadAsStringAsync();
        var tokenData = JsonSerializer.Deserialize&amp;lt;OAuthTokenResponse&amp;gt;(rawResponse);

        return tokenData?.AccessToken;
    }

    public async Task&amp;lt;string?&amp;gt; MakeAuthenticatedRequest(object data)
    {
        var token = await GetAccessTokenAsync();
        if (string.IsNullOrEmpty(token)) return null;

        var client = _httpClientFactory.CreateClient("ApiClient");
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

        var content = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
        var response = await client.PostAsync(_apiSettings.ProtectedEndpoint, content);
        return await response.Content.ReadAsStringAsync();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6: Creating the Controller&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ApiController]
[Route("[controller]")]
public class AuthController : ControllerBase
{
    private readonly ApiService _apiService;

    public AuthController(ApiService apiService)
    {
        _apiService = apiService;
    }

    [HttpPost("send")]
    public async Task&amp;lt;IActionResult&amp;gt; SendData([FromBody] object data)
    {
        var result = await _apiService.MakeAuthenticatedRequest(data);
        if (result == null)
            return StatusCode(500, "Error in sending data");

        return Ok(result);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7: Testing with Postman&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Postman and create a POST request&lt;/li&gt;
&lt;li&gt;Set the URL to:
&lt;code&gt;https://localhost:5001/Auth/send
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add a JSON body with the required data.&lt;/li&gt;
&lt;li&gt;Send the request and check the response.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
In this guide, we've walked through how to implement OAuth 2.0 authentication using the Client Credentials flow in ASP.NET Core. This approach is ideal for securely accessing protected resources and APIs. &lt;/p&gt;

&lt;p&gt;If you found this guide helpful, please leave a comment or share it! 🚀&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>security</category>
      <category>aspdotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
