如何在Azure与.NET Core API中配置OAuth 2.0双授权类型?
在.NET Core API中结合Azure Identity配置双OAuth2授权类型(客户端凭据+授权码)
要实现单个API同时支持服务间的客户端凭据授权和用户侧的授权码授权,你可以通过Azure AD应用注册配置+.NET Core认证/授权策略来完成,具体步骤如下:
1. Azure AD应用注册配置
首先在Azure门户完成API应用的注册和权限设置:
- 启用两种授权类型:在应用注册的"认证"页面,确保勾选"客户端凭据"和"授权码流"(若涉及前端跳转,需添加对应重定向URI)
- 配置API权限:
- 服务间调用:添加应用权限(选择你的API暴露的权限类型),并点击"授予管理员同意"
- 用户访问:添加委派权限,允许用户登录时授权这些权限
- 生成客户端凭据:在"证书和密码"页面创建客户端密钥(或上传证书),用于服务间调用时获取令牌
2. .NET Core项目配置
2.1 配置文件(appsettings.json)
添加Azure AD相关配置项:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "你的Azure AD租户ID", "ClientId": "API应用的客户端ID", "Audience": "API暴露的受众URI(如api://{client-id})" }
2.2 认证与授权服务配置(Program.cs)
添加JWT认证服务,并定义区分两种授权类型的策略:
var builder = WebApplication.CreateBuilder(args); // 添加JWT认证,对接Azure AD builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = $"{builder.Configuration["AzureAd:Instance"]}{builder.Configuration["AzureAd:TenantId"]}"; options.Audience = builder.Configuration["AzureAd:Audience"]; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true }; }); // 定义授权策略,区分两种授权场景 builder.Services.AddAuthorization(options => { // 客户端凭据授权策略:验证令牌来自服务应用 options.AddPolicy("ServiceToService", policy => { policy.RequireAuthenticatedUser(); // 验证令牌的客户端ID(azp声明)为调用服务的应用ID,或检查appid声明 policy.RequireClaim("azp", "调用服务的客户端ID"); // 可选:验证具体的应用权限 // policy.RequireClaim("scp", "Service.Read"); }); // 授权码授权策略:验证令牌来自用户 options.AddPolicy("UserToService", policy => { policy.RequireAuthenticatedUser(); // 用户令牌包含oid(用户对象ID)声明,服务令牌无此声明 policy.RequireClaim("oid"); // 可选:验证具体的委派权限 // policy.RequireClaim("scp", "User.Read"); }); }); builder.Services.AddControllers(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
2.3 控制器中应用策略
在API方法上通过[Authorize]特性指定对应的策略:
[ApiController] [Route("api/service")] public class ServiceController : ControllerBase { // 服务间调用接口,仅允许客户端凭据授权访问 [HttpGet("status")] [Authorize(Policy = "ServiceToService")] public IActionResult GetServiceStatus() { var appId = User.FindFirstValue("appid"); return Ok($"服务 {appId} 访问成功"); } } [ApiController] [Route("api/user")] public class UserController : ControllerBase { // 用户访问接口,仅允许授权码授权访问 [HttpGet("profile")] [Authorize(Policy = "UserToService")] public IActionResult GetUserProfile() { var userId = User.FindFirstValue("oid"); var userName = User.FindFirstValue("name"); return Ok($"用户 {userName}(ID:{userId})访问成功"); } }
关键说明
- 客户端凭据令牌与授权码令牌的核心区别:服务令牌包含
appid声明,无oid声明;用户令牌包含oid、name等用户相关声明 - 权限验证:可以通过
scp声明验证具体的应用/委派权限,实现更细粒度的访问控制 - 调用方处理:服务间调用时,需使用Azure Identity的
ClientSecretCredential或ClientCertificateCredential获取令牌;用户侧调用时,前端需通过授权码流获取令牌后再请求API
内容的提问来源于stack exchange,提问作者ArulPrasath A M
相关产品推荐
相关产品推荐

