You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C# REST API生成Bearer Token?WebJob调用Graph端点实现方法

Great question! Let's break this down clearly—first explaining what a Token endpoint is, then walking through a complete C# implementation for your WebJob.


What is a Token Endpoint?

Think of the Token endpoint as a security checkpoint provided by identity providers like Azure AD (or any OAuth 2.0/OpenID Connect service). Its sole job is to validate your application's identity and permissions, then issue a Bearer Token—the digital "key" you need to access protected APIs like Microsoft Graph.

Here's how it works in practice:

  • You send a POST request to this endpoint with your app's credentials (client ID, client secret), the type of access you need (grant_type), and the specific permissions you're requesting (scope).
  • The endpoint verifies that your app is registered, your credentials are valid, and you have the right permissions.
  • If everything checks out, it sends back an encrypted Bearer Token. This token is what you'll include in every subsequent Graph API request to prove you're authorized.

Common parameters you'll encounter (like in your Postman screenshot) include:

  • client_id: Your app's unique ID from the identity provider's portal
  • client_secret: A secret string tied to your app (keep this secure—never hardcode it!)
  • grant_type: Defines how you're requesting the token—for background services like WebJobs, client_credentials is the right service-to-service flow
  • scope: The specific APIs/permissions you need access to (for Graph, https://graph.microsoft.com/.default uses all the permissions you've configured for your app)

C# REST API Implementation for Your WebJob

Below is a step-by-step implementation using .NET's HttpClient (optimized for WebJob scenarios, with proper dependency injection and resource management).

1. Set Up Configuration (appsettings.json)

Store sensitive values and endpoints in a config file instead of hardcoding:

{
  "AzureAd": {
    "ClientId": "your-app-client-id",
    "ClientSecret": "your-app-client-secret",
    "TokenEndpoint": "https://login.microsoftonline.com/your-tenant-id/oauth2/v2.0/token",
    "GraphApiEndpoint": "https://graph.microsoft.com/v1.0/users" // Example: Fetch user list
  }
}

2. Core WebJob Logic

This class handles fetching the Bearer Token and calling the Graph API:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using System.Text.Json.Serialization;

public class GraphDataJob
{
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _config;

    // Inject dependencies (WebJobs support .NET's dependency injection system)
    public GraphDataJob(HttpClient httpClient, IConfiguration config)
    {
        _httpClient = httpClient;
        _config = config;
    }

    public async Task Execute()
    {
        try
        {
            // Step 1: Fetch Bearer Token from the Token endpoint
            var bearerToken = await GetBearerTokenAsync();
            
            // Step 2: Use the token to call Graph API
            var graphResponse = await CallGraphApiAsync(bearerToken);

            Console.WriteLine("Graph API Response:");
            Console.WriteLine(graphResponse);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Job failed: {ex.Message}");
        }
    }

    private async Task<string> GetBearerTokenAsync()
    {
        var tokenEndpoint = _config["AzureAd:TokenEndpoint"];
        var clientId = _config["AzureAd:ClientId"];
        var clientSecret = _config["AzureAd:ClientSecret"];
        var scope = "https://graph.microsoft.com/.default";

        // Build form data (Token endpoints expect x-www-form-urlencoded format)
        var formContent = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("client_id", clientId),
            new KeyValuePair<string, string>("client_secret", clientSecret),
            new KeyValuePair<string, string>("grant_type", "client_credentials"),
            new KeyValuePair<string, string>("scope", scope)
        });

        // Send POST request to Token endpoint
        var response = await _httpClient.PostAsync(tokenEndpoint, formContent);
        response.EnsureSuccessStatusCode(); // Throws if request fails (e.g., invalid credentials)

        // Parse JSON response to extract the access token
        var tokenResult = await response.Content.ReadFromJsonAsync<TokenResponse>();
        return tokenResult?.AccessToken ?? throw new InvalidOperationException("Failed to retrieve token");
    }

    private async Task<string> CallGraphApiAsync(string bearerToken)
    {
        var graphEndpoint = _config["AzureAd:GraphApiEndpoint"];

        // Create request with Bearer Token in Authorization header
        var request = new HttpRequestMessage(HttpMethod.Get, graphEndpoint);
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);

        // Send request and read response
        var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsStringAsync();
    }

    // Helper class to deserialize Token endpoint response
    private class TokenResponse
    {
        [JsonPropertyName("access_token")]
        public string AccessToken { get; set; }

        [JsonPropertyName("token_type")]
        public string TokenType { get; set; }

        [JsonPropertyName("expires_in")]
        public int ExpiresIn { get; set; }
    }
}

3. WebJob Startup Configuration (Program.cs)

Set up dependency injection and initialize the job:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
{
    b.AddAzureStorageCoreServices(); // Remove if not using Azure Storage triggers
});
builder.ConfigureServices(services =>
{
    services.AddHttpClient(); // Register singleton HttpClient (critical for performance)
    services.AddTransient<GraphDataJob>();
});
builder.ConfigureAppConfiguration((context, config) =>
{
    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
});

var host = builder.Build();
using (host)
{
    var job = host.Services.GetRequiredService<GraphDataJob>();
    await job.Execute();
    await host.RunAsync();
}

Key Production Considerations

  • Token Caching: Cache the Bearer Token using its expires_in value to avoid unnecessary calls to the Token endpoint.
  • Security: Store client_secret in Azure Key Vault or environment variables (never commit it to code repos).
  • Permissions: Ensure your app has the required Graph API application permissions (e.g., User.Read.All) and that admin consent has been granted.
  • Error Handling: Add retries for transient failures (use Polly library for robust retry policies).

内容的提问来源于stack exchange,提问作者Shrad_k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:17:51