我正在使用这个gem向提供者添加Omniauth OpenID。
我在Devise Initializer中配置了gem,一切似乎都正确:
config.omniauth :openid_connect,
{
name: :openid_connect,
scope: %i[openid profile groups_rewardops scope_rewardops],
issuer: ConfigSettings.desjardins.issuer_url,
response_type: :code,
uid_field: 'sub',
response_mode: :query,
discovery: true,
send_scope_to_token_endpoint: false,
client_options:
{
port: 443,
scheme: "https",
host: ConfigSettings.desjardins.host,
authorization_endpoint: "/affwebservices/CASSO/oidc/rewardops/authorize",
token_endpoint: "/affwebservices/CASSO/oidc/rewardops/token",
userinfo_endpoint: "/affwebservices/CASSO/oidc/rewardops/userinfo",
identifier: ConfigSettings.desjardins.client_id,
secret: ConfigSettings.desjardins.client_secret,
redirect_uri: "#{ConfigSettings.api.base_url}front_end/users/auth/openid_connect/callback",
},
}
我有自动取款机的流程是,用户可以登录并向提供商授予访问权限,然后提供商向我的设备回调URL发送带有nonce
、code
和state
的请求。此时,一切似乎都正确,但在尝试生成access_token
时,该请求以failure
结束,并出现以下错误:
ERROR -- omniauth: (openid_connect) Authentication failure! invalid_request: Rack::OAuth2::Client::Error, invalid_request :: Client credentials are invalid.
我确定identifier
和secret
是正确的,不知道发生了什么。
因为我使用的是discovery
模式,所以提供程序的所有配置都在.well-known
中,您可以检查它here
我被阻止了,不知道如何调试错误。检查Rack::OAuth2
以查看错误从何而来,我发现以下内容:
invalid_request: "The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.",
由于某种原因,访问令牌请求的格式似乎不正确,但不确定除了identifier
和secret
之外,我还应该考虑什么?我见过许多其他的配置示例,我的配置似乎是正确的。
1条答案
按热度按时间fiei3ece1#
由于您确信您的凭据是正确的,因此我怀疑正在使用的身份验证方法与提供程序支持的方法之间存在不匹配。检查
.well-known
配置,我发现此提供程序仅支持client_secret_post
。在您的omniauth配置中,我没有看到传递指定身份验证方法的选项。当我深入研究代码时,我看到底层的OAuth2 gem默认使用basic
auth,它使用indentifier
和secret
构造Authentication
头。请参阅:此处的源代码在
client_secret_post
身份验证方法中,客户端不在报头中提供客户端机密,而是授权自己在HTTP请求正文中将机密作为表单参数提供。因此,此提供商看不到您的凭据。您可以通过查看令牌端点请求的日志来验证这一点,令牌端点请求的日志在浏览器中不可见,而是从Rails到提供者的服务器。尝试在您的omniauth配置中的
client_options
散列中传递client_auth_method
。如果您查看我在上面链接的代码中的case语句,似乎没有针对client_secret_post
的命名选项,但它是默认的case。client_auth_method
的任何值看起来都可以工作,但我仍然会使用client_secret_post
。