Reputation: 4320
Im using this gem to add Omniauth OpenID with a provider.
I configured the gem in the Devise Initializer, everything seems to be correct:
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",
},
}
The flow I have atm is that the user can log in and grant access from the provider, then the provider sends a request to my devise callback url with the nonce
, code
and state
. At this point everything seems to be correct but that request ends in failure
when trying to generate the access_token
with the following error:
ERROR -- omniauth: (openid_connect) Authentication failure! invalid_request: Rack::OAuth2::Client::Error, invalid_request :: Client credentials are invalid.
Im sure the identifier
and the secret
are correct, don't understand what's going on.
Since Im using discovery
mode all the configs of the provider are in the .well-known
you can check it here
Im blocked without ideas about how to debug the error. Checking at Rack::OAuth2
to see where the error is comming from I found this that says:
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.",
It seems for some reason the access token request is malformed, but not sure what else apart of identifier
and secret
should I have in mind? I have seen many other examples of configuration and mine seems to be correct.
Upvotes: 1
Views: 1139
Reputation: 520
Since you are sure your credentials are correct, I suspect there is mismatch between the authentication method being used and the methods supported by the provider. Checking the .well-known
config, I see this provider only supports client_secret_post
. In your omniauth config, I see no options being passed to specify the authentication method. When I dive down into the code, I see that the underlying oauth2 gem defaults to using basic
auth, which uses the indentifier
and secret
to construct an Authentication
header. See: source code here
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}"
)
In the client_secret_post
authentication method, instead of providing client secret in the header, the client authorizes itself providing the secret in the HTTP request body as a form parameter. So this provider is not seeing your credentials. You could verify this by looking at the logs of the token endpoint request, which won't be visible in the browser, but rather from your rails BE to the the provider's server.
Try passing a client_auth_method
in the client_options
hash in your omniauth config. If you look at the case statement in the code I linked to above, there doesn't seem to be a named option for client_secret_post
, but it is the default case. Any value for client_auth_method
looks like it would work, but I would still use client_secret_post
.
Upvotes: 2