Omniauth_OpenID_CONNECT GEM-身份验证失败!INVALID_REQUEST:RACK::OAuth2::CLIENT::ERROR,INVALID_REQUEST::客户端凭据无效

c0vxltue  于 2022-09-21  发布在  Ruby
关注(0)|答案(1)|浏览(189)

我正在使用这个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发送带有noncecodestate的请求。此时,一切似乎都正确,但在尝试生成access_token时,该请求以failure结束,并出现以下错误:

ERROR -- omniauth: (openid_connect) Authentication failure! invalid_request: Rack::OAuth2::Client::Error, invalid_request :: Client credentials are invalid.

我确定identifiersecret是正确的,不知道发生了什么。

因为我使用的是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.",

由于某种原因,访问令牌请求的格式似乎不正确,但不确定除了identifiersecret之外,我还应该考虑什么?我见过许多其他的配置示例,我的配置似乎是正确的。

fiei3ece

fiei3ece1#

由于您确信您的凭据是正确的,因此我怀疑正在使用的身份验证方法与提供程序支持的方法之间存在不匹配。检查.well-known配置,我发现此提供程序仅支持client_secret_post。在您的omniauth配置中,我没有看到传递指定身份验证方法的选项。当我深入研究代码时,我看到底层的OAuth2 gem默认使用basic auth,它使用indentifiersecret构造Authentication头。请参阅:此处的源代码

client_auth_method = args.first || options.delete(:client_auth_method).try(:to_sym) || :basic

    case client_auth_method
    when :basic
      cred = Base64.strict_encode64 [
        Util.www_form_url_encode(identifier),
        Util.www_form_url_encode(secret)
      ].join(':')
      headers.merge!(
        'Authorization' => "Basic #{cred}"
      )

client_secret_post身份验证方法中,客户端不在报头中提供客户端机密,而是授权自己在HTTP请求正文中将机密作为表单参数提供。因此,此提供商看不到您的凭据。您可以通过查看令牌端点请求的日志来验证这一点,令牌端点请求的日志在浏览器中不可见,而是从Rails到提供者的服务器。

尝试在您的omniauth配置中的client_options散列中传递client_auth_method。如果您查看我在上面链接的代码中的case语句,似乎没有针对client_secret_post的命名选项,但它是默认的case。client_auth_method的任何值看起来都可以工作,但我仍然会使用client_secret_post

相关问题