首页 文章

Azure AD多租户应用程序 - 如何实现令牌验证?

提问于
浏览
0

我在Azure广告中注册了一个多租户Web应用程序/ API,并连接到API应用程序 . API App具有Active Directory身份验证设置 . 目前只有一个其他租户需要访问api . 我确保只有将 https://sts.windows.net/<third party tenant>/ 放在发卡行URL中才能获得访问权限 . 我的问题是:如何让第二个(或更多)租户访问api?我无法在发卡行URL中添加任何租户ID,所以我有点不知所措

谢谢

1 回答

  • 2

    您当前使用的方法仅适用于单个租户方案,即通过设置IssuerURL自动验证租户仅适用于单个租户方案 .

    在多租户应用程序的情况下,应用程序负责存储和验证所有可能的发布者 . 这是 by design ,此处提供了有关此主题的准确指导:

    Work with claims-based identities in Azure AD: Issuer Validation

    对于单租户应用程序,您可以检查发行者是否是您自己的租户 . 事实上,OIDC中间件默认自动执行此操作 . 在多租户应用中,您需要允许多个发行人,对应于不同的租户 . 以下是一种常用方法:在OIDC中间件选项中,将ValidateIssuer设置为false . 这将关闭自动检查 . 租户注册时,将租户和发行人存储在您的用户数据库中 . 每当用户登录时,在数据库中查找发行者 . 如果未找到发行者,则表示租户尚未注册 . 您可以将它们重定向到注册页面 . 你也可以将某些租户列入黑名单;例如,对于未支付订阅费用的客户 .

    因此,在基于.NET的Web应用程序的情况下,启动类中的代码将更改为类似的内容..请注意 new TokenValidationParameters

    Authenticate using Azure AD and OpenID Connect

    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions {
        ClientId = configOptions.AzureAd.ClientId,
        ClientSecret = configOptions.AzureAd.ClientSecret, // for code flow
        Authority = Constants.AuthEndpointPrefix,
        ResponseType = OpenIdConnectResponseType.CodeIdToken,
        PostLogoutRedirectUri = configOptions.AzureAd.PostLogoutRedirectUri,
        SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,
        TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false },
        Events = new SurveyAuthenticationEvents(configOptions.AzureAd, loggerFactory),
    });
    

    禁用验证颁发者后,您需要自己处理验证 . 以下是一些示例,其中包含有关如何自行执行此验证的一些指导

    Update your code to handle multiple issuer values

    在您通过呼叫之前,您至少需要检查“tid”声明,该声明会根据您自己的有效租户ID列表捕获Azure AD租户ID .

    当单个租户应用程序验证令牌时,它会根据元数据文档中的签名密钥检查令牌的签名,并确保令牌中的颁发者值与元数据文档中找到的值匹配 . 由于/ common endpoints 不对应于租户且不是颁发者,因此当您检查/ common的元数据中的颁发者值时,它具有模板化URL而不是实际值:https://sts.windows . net / /因此,多租户应用程序无法仅通过将元数据中的颁发者值与令牌中的颁发者值进行匹配来验证令牌 . 多租户应用程序需要逻辑来基于发行方值的租户ID部分来决定哪些发行方值有效以及哪些不有效 . 例如,如果多租户应用程序仅允许从已注册其服务的特定租户登录,则必须检查令牌中的颁发者值或tid声明值,以确保租户在其列表中订户 . 如果多租户应用程序仅处理个人并且不根据租户做出任何访问决策,那么它可以完全忽略发行者的 Value .

    (EDIT) More information on Validating Tokens 我正在尝试通过此处的评论回答您的问题 .

    enter image description here

    一个有用的摘录..

    验证声明当应用程序在用户登录时收到访问令牌时,它还应对访问令牌中的声明执行一些检查 . 这些验证包括但不限于:受众声明,验证ID令牌是否打算在不是之前提交给您的应用程序和“到期时间”声明,以验证ID令牌未过期的发行者声明,以验证令牌由v2.0 endpoints 现时发布到您的应用程序,作为令牌重放攻击缓解建议您使用标准库方法(如JwtSecurityTokenHandler.ValidateToken方法(JwtSecurityToken))来执行上述大部分繁重工作 . 您可以根据令牌中收到的声明做出决策,从而进一步扩展验证过程 . 例如,多租户应用程序可以通过检查tid声明的值(租户ID)来扩展标准验证针对一组预先选定的租户,以确保他们只尊重他们选择的租户的令牌 .

    • 示例访问令牌,仅用于理解:访问令牌和Id_token都是简单的base64编码的JSON Web令牌(JWT) . 您可以解码这些以查找声明,然后验证它们 . 我正在分享一个包含代码的示例 . 在此之前,这是来自Microsoft Docs之一的示例访问令牌 . 我刚从here拿了一个例子

    实际值:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N ...(长编码字符串继续)解码值(您可以使用像https://jwt.io这样的网站轻松检查):

    {
      "aud": "https://service.contoso.com/",
      "iss": "https://sts.windows.net/7fe81447-da57-4385-becb-6de57f21477e/",
      "iat": 1388440863,
      "nbf": 1388440863,
      "exp": 1388444763,
      "ver": "1.0",
      "tid": "7fe81447-da57-4385-becb-6de57f21477e",
      "oid": "68389ae2-62fa-4b18-91fe-53dd109d74f5",
      "upn": "frankm@contoso.com",
      "unique_name": "frankm@contoso.com",
      "sub": "deNqIj9IOE9PWJWbHsftXt2EabPVl0Cj8QAmefRLV98",
      "family_name": "Miller",
      "given_name": "Frank",
      "appid": "2d4d11a2-f814-46a7-890a-274a72a7309e",
      "appidacr": "0",
      "scp": "user_impersonation",
      "acr": "1"
    }
    

    正如您所看到的,解码后的值有许多声明,包括您要验证的“tid” .

    希望这可以帮助!

相关问题