【发布时间】:2021-09-24 09:38:02
【问题描述】:
我正在开发一个外部 OAuth 提供程序,以便能够使用我们公司的登录机制让员工和客户连接到雪花。
雪花设置:
首先,为了测试,我创建了一个数据库:
use role accountadmin;
create database fred_ica_db;
create warehouse fred_ica_warehouse;
create role fred_ica_role;
create user fred_ica_user password = '******' login_name = 'upn';
grant usage on database fred_ica_db to role fred_ica_role;
grant usage on warehouse fred_ica_warehouse to role fred_ica_role;
grant role fred_ica_role to user fred_ica_user;
alter user fred_ica_user set DEFAULT_WAREHOUSE='FRED_ICA_WAREHOUSE', DEFAULT_ROLE='FRED_ICA_ROLE' , DEFAULT_NAMESPACE='FRED_ICA_DB.PUBLIC';
并像这样在雪花数据库中创建安全集成对象:
create or replace security integration fred_oauth_integration
type = external_oauth
enabled = true
external_oauth_type = custom
external_oauth_issuer = 'http://$(some_endpoint)/snowflakeAuth/accessToken'
external_oauth_jws_keys_url = 'https://$(aws_account).s3.us-west-2.amazonaws.com/$(public_key_filename)'
external_oauth_audience_list = ('https://xxxx.us-east-1.snowflakecomputing.com')
external_oauth_scope_mapping_attribute = 'scp'
external_oauth_token_user_mapping_claim='upn'
external_oauth_snowflake_user_mapping_attribute='login_name';
第一次尝试:
我创建了私钥/公钥对来处理令牌签名并将公钥上传到 AWS S3,这也将是我们为这个外部 OAuth 提供者提供的生产目标。该文件目前可供公众使用(在公共设备上检查)。公钥格式为:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKC...
...4oQIDAQAB
-----END RSA PUBLIC KEY-----
我的 OAuth 服务器生成一些有效的 JWT 令牌(在 jwt.io 上验证)+ 使用公钥验证的签名:
(Base 64 url 编码)
eyJ0eXAi...wPgXvOtg
并解码:
{
"typ": "JWT",
"alg": "RS256"
}
{
"aud": "https://xxxx.us-east-1.snowflakecomputing.com/",
"scp": [
"session:role:fred_ica_role"
],
"iss": "http://$(some_endpoint)/snowflakeAuth/accessToken",
"exp": 1632483169,
"iat": 1632475969
}
{
...signature...
}
执行时:
select SYSTEM$VERIFY_EXTERNAL_OAUTH_TOKEN('eyJ0eXAi...wPgXvOtg');
带有系统创建的一些令牌 系统返回错误:
令牌验证完成。{"验证结果":"失败","失败原因":"EXTERNAL_OAUTH_JWS_CANT_RETRIEVE_PUBLIC_KEY"}
第二次尝试
(在@Srinath Menon 他的反馈之后)
从公钥中,我创建了一个 json 网络密钥(JWK)。我使用 java 代码创建了它,当我验证时,我注意到也可以使用在线工具来执行此操作。 https://8gwifi.org/jwkconvertfunctions.jsp
我将结果作为文件上传到 AWS S3 上,并确保它是公开可用的,并且内容类型是 application/json :
JWKS:
{"keys":[{"kty":"RSA","e":"AQAB","kid":"5979064a-e202-4321-90ad-8a51329aad61","n":"2636yeJSQqyO5AegaIu6vEHg6w-MzGy1nPy2qj0zJfbDw6O0ATGkG_ibdfWqMHxU-JEBV1wiThv8_Mk67cst4W5U-fg-Miy8SDxYZtIkWFMAeVbamjpi_8BChCIJRVXvS6ZQofGgmFHlJAnWszL0hID8IaHigpBLTNEVHKuPeVGTYg3RcoWTjjB3WtaIj8XqKpQY47EUOiHOa3DZISXteYlfZu9yhQdB-7s0kQhdzk-RiQIHsLfnn-ksVzntmmwHVE5KVllMJt-23bH8c1TbtrMzWHflY85K3iSjhB3EHyeqhZnKuhAR5WVxPxkGIdr9qku1Q6L489R1wRkE2Rk4oQ"}]}
JWK:
{"kty":"RSA","e":"AQAB","kid":"5979064a-e202-4321-90ad-8a51329aad61","n":"2636yeJSQqyO5AegaIu6vEHg6w-MzGy1nPy2qj0zJfbDw6O0ATGkG_ibdfWqMHxU-JEBV1wiThv8_Mk67cst4W5U-fg-Miy8SDxYZtIkWFMAeVbamjpi_8BChCIJRVXvS6ZQofGgmFHlJAnWszL0hID8IaHigpBLTNEVHKuPeVGTYg3RcoWTjjB3WtaIj8XqKpQY47EUOiHOa3DZISXteYlfZu9yhQdB-7s0kQhdzk-RiQIHsLfnn-ksVzntmmwHVE5KVllMJt-23bH8c1TbtrMzWHflY85K3iSjhB3EHyeqhZnKuhAR5WVxPxkGIdr9qku1Q6L489R1wRkE2Rk4oQ"}
这两种方法都会导致相同的错误:
令牌验证完成。{"验证结果":"失败","失败原因":"EXTERNAL_OAUTH_JWS_CANT_RETRIEVE_PUBLIC_KEY"}
【问题讨论】:
-
此网址“https://$(aws_account).s3.us-west-2.amazonaws.com/$(public_key_filename)”是否以纯文本格式返回内容?
-
确实是:curl https://$(aws_account).s3.us-west-2.amazonaws.com/$(public_key_filename)。 -----BEGIN RSA PUBLIC KEY----- MIIBCgKC... ...4oQIDAQAB -----END RSA PUBLIC KEY-----
-
很可能这就是这个问题的原因,期望它应该是 content-type/json 格式。是否传递了任何导致输出以明文形式出现的标头信息?
-
好的,我明白了,我忽略了构建密钥的方式。我将尝试将我的 PEM 文件转换为 JWS 格式。谢谢你的提示。实施后我会为遇到相同问题的人回复结果。
-
更改后我仍然收到相同的错误。 jws_keys_url 端点现在返回如下内容: {"keys":[{"kty":"RSA","kid":"3064f813-2c8f-4d1d-8eb7-6cb32b3d82ee","n":"2636yeJS...kE2Rk4oQ" ,"e":"AQAB"}]} 检查这个 jwk 密钥可以转换为 PEM 并且 PEM 可以转换为 jwk 密钥回到网站8gwifi.org/jwkconvertfunctions.jsp 我还通过剥离“keys” json 容器和通过离开公钥端点返回 {"kty":"RSA","kid":"3064f813-2c8f-4d1d-8eb7-6cb32b3d82ee","n":"2636yeJS...kE2Rk4oQ","e":"AQAB "} 只是,但它给出了相同的结果。
标签: amazon-s3 oauth-2.0 oauth snowflake-cloud-data-platform