azure - Azure 服务应用程序 - 配置启动主机以使用不记名令牌
问题描述
我想使用授权持有者令牌在 Azure 服务应用程序上托管我的 REST API。在 Azure 门户上,我完成了:
- 创建新的应用服务 (testservice)。
- 关于身份验证/授权:
- 应用服务身份验证 -> 开启
- 请求未通过身份验证时要执行的操作 -> 使用 Azure Active Directory 登录。使用管理模式将身份验证提供程序设置为 Active Directory 身份验证:Express 并创建新的 Azure AD 应用程序(注册新应用程序:testserviceapp)
- 令牌存储 -> 开启
- 在应用注册-> testserviceapp:
- 身份验证 -> Web -> 重定向 URI:https ://testservice.azurewebsites.net/.auth/login/aad/callback
- 身份验证 -> Web -> 隐式授权 -> 访问令牌:true,ID 令牌:true
- 身份验证 -> 支持的帐户类型 -> 仅限此组织目录中的帐户(... - 单租户)
- 身份验证 -> 高级设置 -> 将应用程序视为公共客户端:否
- 证书和机密 -> 创建新的 ClientSecret
- 公开 API -> 添加范围:https ://testservice.azurewebsites.net/user_impersonation
- 公开 API -> 添加范围:https ://testservice.azurewebsites.net/WeatherForecast
接下来,我在 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);
}
我究竟做错了什么?
解决方案
推荐阅读
- javascript - JS - 我不明白为什么这个对象声明不起作用
- python - 有没有一种内置方法可以将无参数函数转换为生成器?
- leaflet - 设置多层地图的活动层
- keras - 如何在 resnet50 中应用三元组损失函数以进行深度排名
- spring-cloud-gateway - Spring Cloud Gateway /gateway/refresh 端点不刷新路由
- java - 在Java中注入多个参数相同的接口
- mysql - updateOnDuplicate 无效
- cordova - Ionic Email Composer 插件不适用于 iOS 13+,可能的解决方法?
- html - 为什么我的 DIV 会相互重叠?
- typescript - TSC 后静态成员丢失