首页 > 解决方案 > Azure 服务应用程序 - 配置启动主机以使用不记名令牌

问题描述

我想使用授权持有者令牌在 Azure 服务应用程序上托管我的 REST API。在 Azure 门户上,我完成了:

  1. 创建新的应用服务 (testservice)。
  2. 关于身份验证/授权:
    • 应用服务身份验证 -> 开启
    • 请求未通过身份验证时要执行的操作 -> 使用 Azure Active Directory 登录。使用管理模式将身份验证提供程序设置为 Active Directory 身份验证:Express 并创建新的 Azure AD 应用程序(注册新应用程序:testserviceapp)
    • 令牌存储 -> 开启
  3. 在应用注册-> testserviceapp:

接下来,我在 VisualStudio 中创建了 RestApiService 项目并发布到 Azure。我的 RestApiService 主机中的 appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "AzureAd": {
    "ClientId": "xxx",
    "Domain": "xxx.onmicrosoft.com",
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "xxx",
    "CallbackPath": "/signin-oidc",
    "ClientSecret": "xxx",
    "AppIDURL": "https://testservice.azurewebsites.net",
    "ConfigView": "API"
  }
}

WeatherForecastController.cs:

 [ApiController]
    [Route("[controller]")]
    [Authorize]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

启动.cs:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(AzureADB2CDefaults.BearerAuthenticationScheme).AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

在客户端应用程序上,我成功获得了 AccessToken:

static AuthToken GetToken()
        {
            var uri = "https://login.microsoftonline.com/";
            var method = $"{TenantID}/oauth2/token";
            var client = new RestClient(uri);
            var request = new RestRequest($"{uri}{method}", Method.POST);
            request.AddParameter("grant_type", "client_credentials");
            request.AddParameter("client_id", ClientID);
            request.AddParameter("client_secret", ClientSecret);
            request.AddParameter("resource", "https://testservice.azurewebsites.net/");
            return client.Execute<AuthToken>(request).Data;
        }

但是当我尝试使用此令牌调用 api 时,我收到 401 Unauthorized 错误(您无权查看此目录或页面。):

 static void GetItems(string token)
    {
        var client = new RestClient("https://testservice.azurewebsites.net/");
        var request = new RestRequest("https://testservice.azurewebsites.net/WeatherForecast", Method.GET);
        request.AddHeader("Authorization", $"bearer {token}");
        var response = client.Execute(request);
    }

我究竟做错了什么?

标签: azureauthenticationtokenhost

解决方案


推荐阅读