我正在学习使用 Azure AD 身份验证来验证 API,这是我在 MVC 端配置的代码
public async Task<IEnumerable<Todo>> GetAsync()
{
await PrepareAuthenticatedClient();
var response = await _httpClient.GetAsync($"{ _TodoListBaseAddress}/api/todolist");
if (response.StatusCode == HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
IEnumerable<Todo> todolist = JsonConvert.DeserializeObject<IEnumerable<Todo>>(content);
return todolist;
}
throw new HttpRequestException($"Invalid status code in the HttpResponseMessage: {response.StatusCode}.");
}
private async Task PrepareAuthenticatedClient()
{
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { _TodoListScope });
Debug.WriteLine($"access token-{accessToken}");
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
MVC
appsettings.json
文件
{
"AzureAdB2C":
{
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxx.com",
"TenantId": "4d5c2d64-35d8-4200-805e-xxxxxx11e",
"SignedOutCallbackPath": "/signout",
"ClientSecret": "MMA8Q\~T\~KwXpSqDscijieKycv7Zxxxxxxxxxt",
"ClientId": "c8db825e-be17-4943-b2e5-caxxxxx5"
},
"TodoList":
{
"TodoListScope": "tasks.read",
"TodoListBaseAddress": "https://localhost:44332"
},
"Logging":
{
"LogLevel":
{
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "\*"
}
Web API
Startup
文件:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options => {Configuration.Bind("AzureAdB2C", options);
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = "https://login.microsoftonline.com/",
ValidAudience = "api://c8db825e-be17-4943-b2e5-caf39xxxx",
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
Configuration["AzureAdB2C:ClientSecret"])),
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
// Log detailed information about the failure
Console.WriteLine($"Authentication failed: {context.Exception}");
return Task.CompletedTask;
},
OnChallenge = context =>
{
// Log detailed information about the challenge
Console.WriteLine($"Challenge: {context.Error}, {context.ErrorDescription}");
return Task.CompletedTask;
}
};
},
options => { Configuration.Bind("AzureAdB2C", options); });
services.AddControllers();
}
Web API
appsettings.json
:
{
"AzureAdB2C":
{
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxx.com",
"ClientId": "aeaaab9e-1040-4edf-9f31-5adc3xxxx",
"SignedOutCallbackPath": "/signout/",
"TenantId": "4d5c2d64-35d8-4200-805e-9cdddxxxx",
"ClientSecret": "MMA8Q~T~KwXpSqDscijieKycv7ZWspsnxxxx"
},
"Kestrel":
{
"Endpoints":
{
"Http":
{
"Url": "https://localhost:44332"
}
}
},
"Logging":
{
"LogLevel":
{
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
这是我用来在线获取代码的存储库https://github.com/learnsmartcoding/azure-ad-b2c-authentication-tutorial为Azure中的MVC应用程序和Web API添加了应用程序注册配置
我希望 API 应该接受从 Azure AD 用户生成的令牌。我尝试配置在网上找到的详细信息,但 API 不接受不记名令牌
我创建了一个 ASP。 NET Core API 并使用 Swagger UI 集成 Azure AD 身份验证。
我将以下代码添加到 Program.cs 文件中。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
o =>
{
o.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Azure Ad", Version = "v1" });
o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Name = "oauth2.0",
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(builder.Configuration["SwaggerAAD:AuthorizationUrl"]),
TokenUrl = new Uri(builder.Configuration["SwaggerAAD:TokenUrl"]),
Scopes = new Dictionary<string, string>
{
{builder.Configuration["SwaggerAAD:Scope"],"Access API as User" }
}
}
}
});
o.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
},
new []{builder.Configuration["SwaggerAAD:Scope"]}
}
});
});
app.UseSwaggerUI(
o =>
{
o.OAuthClientId(builder.Configuration["SwaggerAAD:ClientId"]);
o.OAuthUsePkce();
o.OAuthScopeSeparator(" ");
});
}
下面是Program.cs的完整代码:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
o =>
{
o.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Azure Ad", Version = "v1" });
o.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Name = "oauth2.0",
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(builder.Configuration["SwaggerAAD:AuthorizationUrl"]),
TokenUrl = new Uri(builder.Configuration["SwaggerAAD:TokenUrl"]),
Scopes = new Dictionary<string, string>
{
{builder.Configuration["SwaggerAAD:Scope"],"Access API as User" }
}
}
}
});
o.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference=new OpenApiReference{Type=ReferenceType.SecurityScheme,Id="oauth2"}
},
new []{builder.Configuration["SwaggerAAD:Scope"]}
}
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(
o =>
{
o.OAuthClientId(builder.Configuration["SwaggerAAD:ClientId"]);
o.OAuthUsePkce();
o.OAuthScopeSeparator(" ");
});
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
appSettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<YourDomain>.onmicrosoft.com",
"TenantId": "<YourTenantID>",
"ClientId": "<ClientId>",
"CallbackPath": "/signin-oidc",
"Scopes": "access_as_user"
},
"SwaggerAAD": {
"AuthorizationUrl": "https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/authorize",
"TokenUrl": "https://login.microsoftonline.com/<TenantId>/oauth2/v2.0/token",
"Scope": "https://graph.microsoft.com/.default",
"ClientId": "<ClientId>"
}
我为 Azure AD 创建了两个应用程序注册,一个用于 Web API,另一个用于 Swagger 客户端。
在 API 应用程序注册中,转到身份验证 -> 添加平台 -> Web -> 重定向 URI。
https:Localhost:Port/singin-oidc
在 api 中转到公开 Api -> 添加范围。我添加了以下详细信息。
在 swaggerclient 应用程序注册中转到身份验证 -> 添加平台 -> 单页应用程序 -> 重定向 URL,如下所示。
https:Localhost:Port/swagger/oauth2-redirect.html
在 swaggerclient 中转到 API 权限 -> 添加权限 -> 我的 API -> api -> 权限,选择您的范围,如下所示。
运行后点击授权按钮。
选择范围并单击授权按钮。
如下图即登录成功。
输出: