我有一个 dotnet 7.0 应用程序(Web 应用程序),我希望能够通过任何 Azure AD 租户的 SSO 对用户进行身份验证。在 Azure 进行身份验证后,我想查看用户的电子邮件地址和/或某种唯一的用户 ID。
我已在 Azure 门户中的 Azure Active Directory 下创建了一个新的应用程序注册。应用程序注册与我在发行商处的 MPN 帐户相关联。我尝试过使用两种受支持的帐户类型:“多租户”和“任何 Microsoft 帐户”。
我可以成功验证我自己租户的用户身份。但是,当用户尝试向外部租户进行身份验证时,Azure 会向用户抛出错误:
AADSTS50020: User account '[email protected]' from identity provider 'https://sts.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/' does not exist in tenant 'mydomain.com' and cannot access the application 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'(myapp) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
但是我不想在自己的租户中添加用户作为外部用户,因为我还不知道所有用户,而且会太多。我怎样才能让我的应用程序也对来自外部域的用户进行身份验证?
程序.cs:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect; // nuget: Microsoft.Identity.Web
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web; // nuget: Microsoft.Identity.Web
using System.Security.Claims;
var builder = WebApplication.CreateBuilder(args);
var authenticationBuilder = builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme);
authenticationBuilder.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthentication();
app.MapGet("/", (ClaimsPrincipal user, HttpResponse response) =>
{
response.ContentType = "text/html";
if (user.Identity?.IsAuthenticated ?? false)
return $"Hello {user.GetDisplayName()}. <a href='/logout'>Logout</a>.";
else
return $"Hello. You are not authenticated. Please <a href='login'>log in</a>.";
});
app.MapGet("/logout", async context =>
{
await context.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
});
app.MapGet("/login", [Authorize] (ClaimsPrincipal user, HttpResponse response) => response.Redirect("/"));
app.UseRouting();
app.UseAuthorization();
app.Run();
appsettings.json,其值取自 Azure AD 中的应用程序注册:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mydomain.com",
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"CallbackPath": "/signin-oidc"
},
"AllowedHosts": "*"
}
要对多个租户进行身份验证,通过选择“任何组织目录中的帐户(任何 Microsoft Entra ID 租户 - 多租户)”来创建 Azure AD 应用程序:
对于示例,我使用下面的授权端点来验证多租户用户:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/authorize?
&client_id=ClientID
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=https://graph.microsoft.com/.default
&state=12345
当我尝试验证其他租户用户时,我收到了相同的错误,如下所示:
如果 Azure AD 应用程序未配置为多租户,或者您传递了错误的登录 URL 来对其他租户用户进行身份验证,则通常会发生该错误。
注意:要对多个租户用户进行身份验证,您必须创建多租户应用程序并将登录 URL 作为
传递,或者需要传递 organizations 作为租户 ID 的值。https://login.microsoftonline.com/organizations
因此为了解决错误,我修改了授权端点:
https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?
&client_id=ClientID
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=https://graph.microsoft.com/.default
&state=12345
其他租户用户能够成功验证:
要解决此问题,请修改 appsettings.json
文件,为 TenantID 传递
organizations
:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mydomain.com",
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"TenantId": "organizations",
"CallbackPath": "/signin-oidc"
},
"AllowedHosts": "*"
}
我可以使用以下参数通过Postman生成访问令牌:
https://login.microsoftonline.com/organizations/oauth2/v2.0/token
client_id:ClientID
scope:https://graph.microsoft.com/.default
grant_type:authorization_code
redirect_uri:https://jwt.ms
code:code
client_secret:ClientSecret
参考: