Azure AD多租户应用程序-如何实施令牌验证? [英] Azure AD Multi-tenant Applications - How to implement Token Validation?

查看:106
本文介绍了Azure AD多租户应用程序-如何实施令牌验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

谢谢

解决方案

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

对于多租户应用程序,该应用程序负责存储和验证所有可能的发行者.这是设计目的,有关Microsoft的此主题的确切指南,请参见此处:

在以下环境中使用基于声明的身份Azure AD:发行者验证

对于单租户应用程序,您只需检查发行者是否为 您自己的房客.实际上,OIDC中间件会自动执行此操作 默认情况下.在多租户应用中,您需要允许多个 发行人,对应于不同的租户.这是一般 使用方法:

  • 在OIDC中间件选项中,将ValidateIssuer设置为false.这将关闭自动检查.
  • 租户签署后,将租户和发行方存储在用户数据库中.
  • 无论何时用户登录,都要在数据库中查找发行人,如果未找到发行人,则意味着租户尚未注册.你 可以将他们重定向到注册页面.
  • 您还可以将某些租户列入黑名单;例如,针对未付费订阅的客户.

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

使用Azure进行身份验证AD和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),
});

一旦您禁用了验证发行者,您将需要自己处理验证.这是一个示例,其中包含一些有关如何自己进行验证的指南

当单个租户应用程序验证令牌时,它会检查 根据元数据中的签名密钥对令牌进行签名 文档,并确保令牌中的发行者值与 在元数据文档中找到的.

由于/common端点与租户不对应,并且不是 发行者,当您检查/common元数据中的发行者值时 它具有模板网址,而不是实际值:

https://sts.windows.net/ {tenantid}/

因此,多租户应用程序不能仅通过以下方式验证令牌 将元数据中的发行者值与 令牌.多租户应用程序需要逻辑来决定哪个发行者 值是有效的,而无效的则基于的租户ID部分 发行人的价值.

例如,如果多租户应用程序仅允许来自 已签署服务的特定租户,则必须 检查令牌中的发行者值或tid声明值以 确保租户在其订户列表中.如果一个 多租户应用程序仅与个人打交道,而不会 任何基于租户的访问决策,那么它都可以忽略发行者 完全有价值.

(编辑)有关验证令牌的更多信息 我正在尝试通过此处的评论回答您的问题.

  1. 这是示例代码,它执行手动验证JWT令牌的任务.

    1. 样本访问令牌,仅用于理解:访问令牌和Id_token都是简单的base64编码的JSON Web令牌(JWT).您可以对它们进行解码以找到声明,然后对其进行验证.我正在共享一个示例,该示例具有执行此操作的代码.在此之前,这里是来自Microsoft Docs的示例访问令牌.我只是从 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".

      希望这会有所帮助!

      I have a multi tenant Web app / API registered in Azure ad and that connected to an API App. The API App has Active Directory Authentication setup. At the moment only one other tenant needs access to api. I made sure only they can get access by putting https://sts.windows.net/<third party tenant>/ in the Issuer URL. My question is: How would I go about giving a second (or more) tenants access to the api? I can't add anymore tenant ids in the Issuer URL so I'm kinda at a loss

      Thanks

      解决方案

      The approach you are using currently will work only in a single tenant scenario, i.e. Automatic validation of tenant by setting IssuerURL works only in a single tenant scenario.

      In case of multi-tenant applications, the application is responsible for storing and validating all possible issuers. This is by design and exact guidance on this topic from Microsoft is available here:

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

      For a single-tenant application, you can just check that the issuer is your own tenant. In fact, the OIDC middleware does this automatically by default. In a multi-tenant app, you need to allow for multiple issuers, corresponding to the different tenants. Here is a general approach to use:

      • In the OIDC middleware options, set ValidateIssuer to false. This turns off the automatic check.
      • When a tenant signs up, store the tenant and the issuer in your user DB.
      • Whenever a user signs in, look up the issuer in the database.If the issuer isn't found, it means that tenant hasn't signed up. You can redirect them to a sign up page.
      • You could also blacklist certain tenants; for example, for customers that didn't pay their subscription.

      So, in case of a .NET based web application the code in your startup class would change to something like this.. notice the new TokenValidationParameters { ValidateIssuer = false }

      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),
      });
      

      Once you have disabled the Validate issuer, you will need to handle the validation yourself. Here is a sample with some guidance around how to do this validation yourself

      Update your code to handle multiple issuer values

      You will at least need to check the "tid" claim which captures the Azure AD Tenant Id against your own list of valid tenant IDs, before you let the call go through.

      When a single tenant application validates a token, it checks the signature of the token against the signing keys from the metadata document, and makes sure the issuer value in the token matches the one that was found in the metadata document.

      Since the /common endpoint doesn’t correspond to a tenant and isn’t an issuer, when you examine the issuer value in the metadata for /common it has a templated URL instead of an actual value:

      https://sts.windows.net/{tenantid}/

      Therefore, a multi-tenant application can’t validate tokens just by matching the issuer value in the metadata with the issuer value in the token. A multi-tenant application needs logic to decide which issuer values are valid and which are not, based on the tenant ID portion of the issuer value.

      For example, if a multi-tenant application only allows sign in from specific tenants who have signed up for their service, then it must check either the issuer value or the tid claim value in the token to make sure that tenant is in their list of subscribers. If a multi-tenant application only deals with individuals and doesn’t make any access decisions based on tenants, then it can ignore the issuer value altogether.

      (EDIT) More information on Validating Tokens I'm trying to answer your questions from comments here.

      1. Here is sample code which does the task of manually validating JWT tokens. Manually validating a JWT access token in a web API

      A useful excerpt..

      Validating the claims When an application receives an access token upon user sign-in, it should also perform a few checks against the claims in the access token. These verifications include but are not limited to:

      audience claim, to verify that the ID token was intended to be given to your application not before and "expiration time" claims, to verify that the ID token has not expired issuer claim, to verify that the token was issued to your app by the v2.0 endpoint nonce, as a token replay attack mitigation You are advised to use standard library methods like JwtSecurityTokenHandler.ValidateToken Method (JwtSecurityToken) to do most of the aforementioned heavy lifting. You can further extend the validation process by making decisions based on claims received in the token. For example, multi-tenant applications can extend the standard validation by inspecting value of the tid claim (Tenant ID) against a set of pre-selected tenants to ensure they only honor token from tenants of their choice.

      1. Sample Access Token, just for understanding: Access Token and Id_token are both simple base64 encoded JSON Web Tokens (JWT). You can decode these to find the claims and then validate them. I'm sharing a sample which has code to do just that. Before that here is a sample access token from one of Microsoft Docs. I just took one for example from here

      Actual Value: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N... (a long encoded string continues) Decoded Value (you can check this easily using a website like 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"
      }
      

      As you can see the decoded value has many claims including "tid" which you're about to validate.

      Hope this helps!

      这篇关于Azure AD多租户应用程序-如何实施令牌验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆