简体   繁体   English

Snowflake:为外部 OAuth 配置 Microsoft Azure AD - 管理员同意

[英]Snowflake: Configure Microsoft Azure AD for External OAuth - admin consent

I am using this guide to configure Microsoft Azure AD for external OAuth in Snowflake.我正在使用指南为 Snowflake 中的外部 OAuth 配置 Microsoft Azure AD。 I'm pretty sure that I followed all the steps because tried that meticulously on three Azure subscriptions and got the same result.我很确定我遵循了所有步骤,因为在三个 Azure 订阅上仔细尝试并得到了相同的结果。

Every time I got stuck at the testing procedure section where I'm supposed to send a request to Azure AD to get an access token:每次我被困在测试程序部分时,我应该向 Azure AD 发送请求以获取访问令牌:

curl -X POST -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
  --data-urlencode "client_id=<OAUTH_CLIENT_ID>" \
  --data-urlencode "client_secret=<OAUTH_CLIENT_SECRET>" \
  --data-urlencode "username=<AZURE_AD_USER>" \
  --data-urlencode "password=<AZURE_AD_USER_PASSWORD>" \
  --data-urlencode "grant_type=password" \
  --data-urlencode "scope=session:role:analyst" \
  '<AZURE_AD_OAUTH_TOKEN_ENDPOINT>'

I am a subscription owner and definitely granted admin access to the session:role:analyst scope:我是订阅所有者,并且明确授予了对session:role:analyst scope 的管理员访问权限: 在此处输入图像描述

However, instead of the access token, I get the following response:但是,我得到的不是访问令牌,而是以下响应:

{
    "error": "invalid_grant",
    "error_description": "AADSTS65001: The user or administrator has not consented to use the application with ID '...' named 'Snowflake OAuth Client'. Send an interactive authorization request for this user and resource.\r\nTrace ID: ...\r\nCorrelation ID: ...\r\nTimestamp: ...",
    "error_codes": [
        65001
    ],
    "timestamp": "...",
    "trace_id": "...",
    "correlation_id": "...",
    "suberror": "consent_required"
}

Tried to grant the consent by reaching https://login.microsoftonline.com/{{tenant_id}}/adminconsent?client_id={{client_id}} and after granting the consent, got an error: AADSTS500113: No reply address is registered for the application.试图通过到达https://login.microsoftonline.com/{{tenant_id}}/adminconsent?client_id={{client_id}}来授予同意,并在授予同意后出现错误: AADSTS500113: No reply address is registered for the application.

Found this and added the return URL http://localhost/ (without a clear understanding of why).找到这个并添加了 return URL http://localhost/ (不清楚为什么)。 Granted the consent again and was redirected to http://localhost/?admin_consent=True&tenant={{tenant_id}}# which, I suppose, is fine.再次同意并被重定向到 http://localhost/?admin_consent=True&tenant={{tenant_id}}# 我想这很好。

But I still get AADSTS65001: The user or administrator has not consented to use the application .但我仍然收到AADSTS65001: The user or administrator has not consented to use the application

Reached to Microsoft documentation and figured out that using grant_type=password is not recommended - makes sense.访问了 Microsoft 文档并发现不推荐使用grant_type=password - 有道理。

Tried grant_type=client credentials:尝试过grant_type=client credentials:

curl --location --request GET 'https://login.microsoftonline.com/{{tenant_id}}/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id={{client_id}}' \
--data-urlencode 'scope=https://graph.microsoft.com/.default' \
--data-urlencode 'client_secret={{client_secret}}'

Got the access token, but attempts to connect to Snowflake with a connection string like:获得了访问令牌,但尝试使用如下连接字符串连接到 Snowflake:

connection.ConnectionString = $"account={account};host={host};authenticator=oauth;user={oauthUser};token={token};";

Throw Snowflake.Data.Client.SnowflakeDbException: 'Invalid OAuth access token.抛出Snowflake.Data.Client.SnowflakeDbException: 'Invalid OAuth access token. . .

I suspect this is because scope=https://graph.microsoft.com/.default , but replacing it with session:scope:analyst brings this:我怀疑这是因为scope=https://graph.microsoft.com/.default ,但是用session:scope:analyst替换它会带来这个:

{
    "error": "invalid_scope",
    "error_description": "AADSTS1002012: The provided value for scope session:scope:analyst is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).\r\nTrace ID: ...\r\nCorrelation ID: ...\r\nTimestamp: ...",
    "error_codes": [
        1002012
    ],
    "timestamp": "...",
    "trace_id": "...",
    "correlation_id": "..."
}

Since I already deviated from the official Snowflake guide, I'm asking the community for help with this issue.由于我已经偏离了官方 Snowflake 指南,因此我向社区寻求有关此问题的帮助。 Thank you in in advance!提前谢谢你!

When obtaining an access token with the Resource Owner Password Credentials Grant flow (which is not recommended and you really shouldn't do), the resulting access token is for accessing a resource (API) on behalf of the signed-in user.当使用资源所有者密码凭据授予流程获取访问令牌时(推荐,您确实不应该这样做),生成的访问令牌用于代表登录用户访问资源 (API)。 In the Microsoft identity platform, access on behalf of a user requires the client application be granted at least one delegated permissions to the requested resource.在 Microsoft 标识平台中,代表用户进行访问要求客户端应用程序至少被授予对所请求资源的一种委派权限。

In your screenshot, we see that the permission you granted for "Snowflake OAuth Resource" is an application permission (aka "app role").在您的屏幕截图中,我们看到您授予“Snowflake OAuth Resource”的权限是应用程序权限(又名“应用程序角色”)。

You need to do two things:你需要做两件事:

  1. On the resource app's app registration, make sure you followed sub-step 10 under Step 1: Configure the OAuth Resource in Azure AD , and defined "session:scope:analyst" as a delegated permission (scope).在资源应用程序的应用程序注册中,确保您遵循了第 1 步:在 Azure AD 中配置 OAuth 资源下的子步骤 10,并将“session:scope:analyst”定义为委派权限(范围)。
  2. In the client's app registration, under API permissions, choose the corresponding delegated permission for the resource, and grant it.在客户端的app注册中,在API权限下,为资源选择对应的委托权限,并授予。

Then, when you go to test obtaining the token, make sure the "scope" parameter is the full scope value, including the resource's identifier URI (which you defined in sub-step 9).然后,当您 go 测试获取令牌时,请确保“范围”参数是完整的 scope 值,包括资源的标识符 URI(您在子步骤 9 中定义)。 For example, if your identifier URI is https://my.snowflake.example.com , then the "scope" value would be https://my.snowflake.example.com/session:role:analyst and your cURL request would be:例如,如果您的标识符 URI 是https://my.snowflake.example.com ,则“范围”值将为https://my.snowflake.example.com/session:role:analyst并且您的 cURL 请求将是:

curl -X POST -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
  --data-urlencode "client_id=<OAUTH_CLIENT_ID>" \
  --data-urlencode "client_secret=<OAUTH_CLIENT_SECRET>" \
  --data-urlencode "username=<AZURE_AD_USER>" \
  --data-urlencode "password=<AZURE_AD_USER_PASSWORD>" \
  --data-urlencode "grant_type=password" \
  --data-urlencode "scope=https://my.snowflake.example.com/session:role:analyst" \
  '<AZURE_AD_OAUTH_TOKEN_ENDPOINT>'

WARNING : The Resource Owner Password Credentials Grant flow is not recommended.警告:不建议使用资源所有者密码凭据授予流程。 I suggest reaching out to app publishers who are suggesting you use this flow.我建议联系建议您使用此流程的应用发行商。 Here is Microsoft's warning on the subject :以下是微软对这个问题的警告

Microsoft recommends you do not use the ROPC flow. Microsoft 建议您不要使用 ROPC 流程。 In most scenarios, more secure alternatives are available and recommended.在大多数情况下,可以使用并推荐更安全的替代方案。 This flow requires a very high degree of trust in the application, and carries risks which are not present in other flows.此流程需要对应用程序有非常高的信任度,并且会带来其他流程中不存在的风险。 You should only use this flow when other more secure flows can't be used.您应该仅在无法使用其他更安全的流程时才使用此流程。

If the set up is still configured for "password" type grant credentials then the issue there is with the scope which should be set up on AAD and passed as follows:如果设置仍配置为“密码”类型的授权凭证,则 scope 存在问题,应在 AAD 上设置并按如下方式传递:

**session:role-<name>**

Note, that the hyphen between role and name and it's not a colon.请注意,角色和名称之间的连字符不是冒号。

In your setup, it seems to be set up and passed as:在您的设置中,它似乎被设置并传递为:

session:role:<name>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM