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

多租户Azure Web App与Web Job的身份验证/授权共享咨询

Solution Overview

We'll split this into three core parts: setting up multi-tenant authentication in the Web App, passing user context to the Web Job securely, and modifying the Web Job to use delegated permissions via refresh tokens.

1. Configure Multi-Tenant App Registration

  • Update your app registration to support multi-tenant accounts (set "Supported account types" to "Any Azure AD directory").
  • Add delegated permissions (e.g., Mail.Read, offline_access) and ensure admin consent is granted for your tenant (or let users consent individually if allowed).
  • Enable the offline_access permission to obtain refresh tokens, which the Web Job can use to get access tokens for the user's tenant over time.

2. Implement User Login in the Web App

Use the Microsoft.Identity.Web library to handle authentication and token acquisition in your ASP.NET Core Web App:

Web App Setup (Program.cs)

var builder = WebApplication.CreateBuilder(args);

// Add authentication with Microsoft Identity
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi(new[] { "Mail.Read", "offline_access" })
    .AddInMemoryTokenCaches();

builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Retrieve Refresh Token and Trigger Web Job

In your Web App controller, after user login, fetch the refresh token and send a message to Azure Queue Storage to trigger the Web Job asynchronously:

using Azure.Storage.Queues;
using Microsoft.Identity.Web;
using System.Text.Json;

public class HomeController : Controller
{
    private readonly ITokenAcquisition _tokenAcquisition;
    private readonly IConfiguration _configuration;

    public HomeController(ITokenAcquisition tokenAcquisition, IConfiguration configuration)
    {
        _tokenAcquisition = tokenAcquisition;
        _configuration = configuration;
    }

    public async Task<IActionResult> TriggerWebJob()
    {
        // Get refresh token for the logged-in user
        var refreshToken = await _tokenAcquisition.GetRefreshTokenAsync(
            new[] { "Mail.Read", "offline_access" },
            user: User);

        // Extract tenant ID from user claims
        var tenantId = User.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid")?.Value;

        // Send job details to Azure Queue
        var queueClient = new QueueClient(
            _configuration["AzureStorage:ConnectionString"], 
            "webjob-task-queue");
        await queueClient.CreateIfNotExistsAsync();

        var jobPayload = new JobPayload
        {
            TenantId = tenantId,
            RefreshToken = refreshToken,
            Scopes = new[] { "Mail.Read" }
        };

        await queueClient.SendMessageAsync(JsonSerializer.Serialize(jobPayload));

        return RedirectToAction("Index");
    }
}

// Helper class for queue message serialization
public class JobPayload
{
    public string TenantId { get; set; }
    public string RefreshToken { get; set; }
    public string[] Scopes { get; set; }
}

Note: Store sensitive values like queue connection strings in Azure Key Vault, not plaintext config files.

3. Modify Web Job Code to Use Delegated Permissions

Update your Web Job to use RefreshTokenCredential (from Azure.Identity) instead of ClientSecretCredential. This credential uses the user's refresh token to authenticate and fetch access tokens for their tenant:

Modified Web Job Code

using Azure.Identity;
using Microsoft.Graph;
using System.Text.Json;

// Queue-triggered Web Job function
public static async Task ProcessQueueTask([QueueTrigger("webjob-task-queue")] string message, ILogger logger)
{
    var jobPayload = JsonSerializer.Deserialize<JobPayload>(message);
    
    // Fetch app credentials from Web Job config
    var clientId = Environment.GetEnvironmentVariable("ClientId");
    var clientSecret = Environment.GetEnvironmentVariable("ClientSecret");

    var credentialOptions = new TokenCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
    };

    // Create credential using user's refresh token
    var refreshTokenCredential = new RefreshTokenCredential(
        tenantId: jobPayload.TenantId,
        clientId: clientId,
        refreshToken: jobPayload.RefreshToken,
        clientSecret: clientSecret,
        options: credentialOptions);

    var graphClient = new GraphServiceClient(refreshTokenCredential, jobPayload.Scopes);

    // Example: Fetch user's recent messages
    var messages = await graphClient.Me.Messages.Request().Take(10).GetAsync();
    logger.LogInformation($"Retrieved {messages.Count} messages for the user.");
}

// Reuse the same JobPayload class from the Web App
public class JobPayload
{
    public string TenantId { get; set; }
    public string RefreshToken { get; set; }
    public string[] Scopes { get; set; }
}

Web Job Configuration

  • Store your multi-tenant app's ClientId and ClientSecret in the Web Job's application settings (Azure Portal > Your Web App > Web Jobs > Configuration).
  • Ensure the Web Job has permissions to read from the target Azure Queue Storage.

Key Considerations

  • Refresh Token Security: Refresh tokens are long-lived, so encrypt them when storing or transmitting. Use Azure Key Vault to store refresh tokens instead of sending them directly in queue messages (send a secret ID reference instead).
  • Token Management: The RefreshTokenCredential automatically handles refreshing access tokens using the refresh token, so you don't need to manage token expiry manually.
  • User Consent: Ensure users have consented to the required delegated permissions (e.g., Mail.Read) when logging into the Web App.
  • Admin Consent Flow: If your app requires permissions that need tenant admin approval, implement a consent flow for admins to grant access across their tenant.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:40:35