无法限制多租户应用程序中的身份验证颁发者(Blazor Server App/OpenIDConnect/Azure App Services)

时间:2021-03-14 18:31:52

标签: authentication azure-web-app-service openid-connect multi-tenant blazor-server-side

我正在尝试向部署在 Azure 应用服务中的 Blazor 服务器应用添加多租户身份验证和授权。场景非常基础:

  1. 允许多租户身份验证(运行良好)
  2. 将身份验证限制为指定的租户/颁发者(此代码在 startup.cs 中)
  3. 授权经过身份验证的用户

但第 2 步失败了。当我在 Azure 中部署我的应用程序时,我仍然可以使用来自未经验证的颁发者的帐户打开应用程序。这是我的代码(startup.cs):

public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                    .AddMicrosoftIdentityWebApp(options =>
                    {
                        Configuration.Bind("AzureAd", options);
                        // Restrict users to specific belonging to specific tenants
                        options.TokenValidationParameters = new TokenValidationParameters 
                        {   ValidateIssuer = true,
                            // Tried first this, but with no effect:
                            // ValidIssuers = new List<string> {
                            //    "https://sts.windows.net/<tenant1>/",
                            //    "https://sts.windows.net/<tenant2>/"
                            //},
                            //So instead tried to use IssuerValidator, but this did not restrict access either:
                            IssuerValidator = ValidateSpecificIssuers
                        };
                    });

            services.AddControllersWithViews()
                .AddMicrosoftIdentityUI();
//...

private string[] GetAcceptedTenantIds()
        {
            return new[]
            {
            "<tenant1>",
            "<tenant2>",
            };
        }

        public string ValidateSpecificIssuers(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
        {
            var validIssuers = GetAcceptedTenantIds().Select(tid => "https://login.microsoftonline.com/{tid}");
            if (validIssuers.Contains(issuer))
            {
                return issuer;
            }
            else
            {
                throw new SecurityTokenInvalidIssuerException("The sign-in user's account does not belong to one of the tenants that this Web App accepts users from.");
            }
        }

我正在使用具有多组织身份验证的 Visual Studio Blazor Server App 项目模板。相关代码部分没有其他更改(appsettings.json 中的“TenantId”:“organizations”除外)。 我发现了这个 post,它说 ValidIssuer(s) 的行为不像人们预期的那样。这就是我尝试使用 IssuerValidator 的原因。不幸的是,结果相同。

我错过了什么?接下来我应该尝试什么?

1 个答案:

答案 0 :(得分:0)

我终于弄明白了(感谢@JimXu,他说我应该使用 fiddler)。 问题出在我的Azure 应用服务应用注册设置中:

  1. 我有应用服务身份验证“开启”。因此,身份验证过程使用的是(https://login.microsoftonline.com/kmsi 重定向到 https://myapp.azurewebsites.net/.auth/login/aad/callback)而不是我的应用程序代码(重定向到 https://myapp.azurewebsites.net/singin-oidc) --> "Off"
  2. .auth/login/aad/callback 有效,因为我还将 https://myapp.azurewebsites.net/.auth/login/aad/callback 添加到我的应用注册重定向 URI --> 已删除

ValidIssuers 不足以限制用户,所以我必须在那里安装 IssuerValidator。代码现在看起来像这样:

...
public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(options =>
                {
                    Configuration.Bind("AzureAd", options);
                    options.TokenValidationParameters = new TokenValidationParameters 
                    {   ValidateIssuer = true,
                        IssuerValidator = ValidateSpecificIssuers
                    };
                });

...

private string[] GetAcceptedIssuers()
    {
        return new[]
        {
        "https://login.microsoftonline.com/<tenant1>/v2.0",
        "https://login.microsoftonline.com/<tenant2>/v2.0",
        };
    }

public string ValidateSpecificIssuers(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters)
    {
        var validIssuers = GetAcceptedIssuers();
        if (validIssuers.Contains(issuer))
        {
            return issuer;
        }
        else
        {
            throw new SecurityTokenInvalidIssuerException("The sign-in user's account does not belong to one of the tenants that this Web App accepts users from.");
        }
    }
相关问题