How to configure OpenID Connect with Drupal 8 OAuth module as the provider?

I’m trying to set up a Drupal 8 site as my Oauth/OpenID Connect provider. The module’s documentation is sparse, as is my understanding of all the pieces. I am reading up on OAuth and OpenID Connect so I can hopefully be smarter in my troubleshooting, but in the meantime, help would be appreciated.

I know the module works as an Open ID Connect provider. I was able to configure a different Drupal 8 site to connect via the OpenID Connect module. I only needed the authorize, token, and userinfo endpoints to make it work.

Here are the module docs

The module’s routing file lists these routes:

  • ‘/oauth2/authorize’
  • ‘/oauth2/token’
  • ‘/oauth2/tokens/{oauth2_server_token}’
  • ‘/oauth2/UserInfo’
  • ‘/oauth2/certificates’

The OAuth2 Server module has you configure a server, and then you configure individual clients for that server.

The server config:

The client config:

The module does not provide a .well-known endpoint, so I am using provider-params as documented here.

Here is my OwnCloud config:

$CONFIG['openid-connect'] = [
  'autoRedirectOnLoginPage' => false,
  'client-id' => 'owncloud_example_org',
  'client-secret' => 'secret',
  'loginButtonName' => 'OpenId Connect',
  'mode' => 'userid',
  'provider-params' => [
    'authorization_endpoint' => 'https://drupal.example.org/oauth2/authorize',
    //'end_session_endpoint' => '...',
    //'jwks_uri' => '...',
    //'registration_endpoint' => '...',
    'token_endpoint' => 'https://drupal.example.org/oauth2/token',
    //'token_endpoint_auth_methods_supported' => '...',
    'userinfo_endpoint' => 'https://drupal.example.org/oauth2/UserInfo'    
  ],
  'provider-url' => 'https://drupal.example.org',
  'search-attribute' => 'sub',
  'use-token-introspection-endpoint' => true,
  'insecure' => true,
];

I left settings I didn’t know about commented out.

When I click the OpenId Connect button, I am successfully sent to the Drupal site’s authorization page. But after hitting the “authorize” button and being redirected back to OwnCloud, I hit an error message.

Error in OpenIdConnect:Unable to determine state

The url looks like: https://owncloud.example.org/apps/openidconnect/redirect?code=< hash >&state=< hash2 >

In the owncloud log file I see:

{"reqId":"kB2PmFbDrPQJnJptNLyi","level":3,"time":"2021-04-16T22:01:24+00:00","remoteAddr":"192.168.122.1","user":"--","app":"OpenID","method":"GET","url":"\/apps\/openidconnect\/redirect?code=276d452e31bc1a761e3c41ac302e6024a8e715a4&state=4812593433c06ac171f1a5d17b51d822","message":"Exception: {\"Exception\":\"Jumbojett\\\\OpenIDConnectClientException\",\"Message\":\"Unable to determine state\",\"Code\":0,\"Trace\":\"#0 \\\/var\\\/www\\\/owncloud\\\/apps\\\/openidconnect\\\/lib\\\/Client.php(164): Jumbojett\\\\OpenIDConnectClient->authenticate()\\n#1 \\\/var\\\/www\\\/owncloud\\\/apps\\\/openidconnect\\\/lib\\\/Controller\\\/LoginFlowController.php(124): OCA\\\\OpenIdConnect\\\\Client->authenticate()\\n#2 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/Http\\\/Dispatcher.php(153): OCA\\\\OpenIdConnect\\\\Controller\\\\LoginFlowController->login(*** sensitive parameters replaced ***)\\n#3 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/Http\\\/Dispatcher.php(85): OC\\\\AppFramework\\\\Http\\\\Dispatcher->executeController()\\n#4 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/App.php(100): OC\\\\AppFramework\\\\Http\\\\Dispatcher->dispatch()\\n#5 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/Routing\\\/RouteActionHandler.php(47): OC\\\\AppFramework\\\\App::main()\\n#6 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/Route\\\/Router.php(341): OC\\\\AppFramework\\\\Routing\\\\RouteActionHandler->__invoke()\\n#7 \\\/var\\\/www\\\/owncloud\\\/lib\\\/base.php(915): OC\\\\Route\\\\Router->match()\\n#8 \\\/var\\\/www\\\/owncloud\\\/index.php(54): OC::handleRequest()\\n#9 {main}\",\"File\":\"\\\/var\\\/www\\\/owncloud\\\/apps\\\/openidconnect\\\/vendor\\\/jumbojett\\\/openid-connect-php\\\/src\\\/OpenIDConnectClient.php\",\"Line\":312}"}

Any suggestions on troubleshooting steps? I have tried a bunch of different combinations of settings, but nothing worked. And I didn’t do it in a smart way, so no notes…

Is the app expecting different parameters in the url? Is there a way to tell it which parameters to use?

Thanks in advance!

I found a module that provides openid connect autodiscovery. When I use curl, here is what I get:

curl --insecure https://drupal.example.org/.well-known/openid-configuration
{
  "authorization_endpoint": "http://drupal.example.org/oauth2/authorize",
  "end_session_endpoint": "http://drupal.example.org/user/logout",
  "id_token_signing_alg_values_supported": "RS256",
  "issuer": "http://drupal.example.org/",
  "jwks_uri": "http://drupal.example.org/.well-known/openid-jwks",
  "response_types_supported": [
    "code",
    "token"
  ],
  "subject_types_supported": [
    "public"
  ],
  "token_endpoint": "http://drupal.example.org/oauth2/token",
  "userinfo_endpoint": "http://drupal.example.org/oauth2/UserInfo"
}

When I configure my OwnCloud config to look like:

$CONFIG['openid-connect'] = [
  'autoRedirectOnLoginPage' => false,
  'client-id' => 'owncloud_example_org',
  'client-secret' => 'secret',
  'loginButtonName' => 'OpenId Connect',
  'mode' => 'userid',
  'provider-url' => 'https://drupal.example.org',
  'search-attribute' => 'sub',
  'insecure' => true,
];

I run into this error after authorizing OwnCloud:

Error in OpenIdConnect:The grant type was not specified in the request

Any suggestions?

Anyone have any suggestions? I haven’t been able to figure anything new out yet.

Ok, so, I switched from Drupal to KeyCloak. Now I’m back at the “Unable to determine state” error.

{
\"Exception\":\"Jumbojett\\\\OpenIDConnectClientException\",
\"Message\":\"Unable to determine state\",
\"Code\":0,
\"Trace\":\"
#0 \\\/var\\\/www\\\/owncloud\\\/apps\\\/openidconnect\\\/lib\\\/Client.php(164): Jumbojett\\\\OpenIDConnectClient->authenticate()\\n
#1 \\\/var\\\/www\\\/owncloud\\\/apps\\\/openidconnect\\\/lib\\\/Controller\\\/LoginFlowController.php(124): OCA\\\\OpenIdConnect\\\\Client->authenticate()\\n
#2 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/Http\\\/Dispatcher.php(153): OCA\\\\OpenIdConnect\\\\Controller\\\\LoginFlowController->login(*** sensitive parameters replaced ***)\\n
#3 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/Http\\\/Dispatcher.php(85): OC\\\\AppFramework\\\\Http\\\\Dispatcher->executeController()\\n
#4 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/App.php(100): OC\\\\AppFramework\\\\Http\\\\Dispatcher->dispatch()\\n
#5 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/AppFramework\\\/Routing\\\/RouteActionHandler.php(47): OC\\\\AppFramework\\\\App::main()\\n
#6 \\\/var\\\/www\\\/owncloud\\\/lib\\\/private\\\/Route\\\/Router.php(341): OC\\\\AppFramework\\\\Routing\\\\RouteActionHandler->__invoke()\\n
#7 \\\/var\\\/www\\\/owncloud\\\/lib\\\/base.php(915): OC\\\\Route\\\\Router->match()\\n
#8 \\\/var\\\/www\\\/owncloud\\\/index.php(54): OC::handleRequest()\\n
#9 {main}\",\"File\":\"\\\/var\\\/www\\\/owncloud\\\/apps\\\/openidconnect\\\/vendor\\\/jumbojett\\\/openid-connect-php\\\/src\\\/OpenIDConnectClient.php\",\"Line\":312}"}

In OpenIDConnectClient.php

            // Do an OpenID Connect session check
            if ($_REQUEST['state'] !== $this->getState()) {
                throw new OpenIDConnectClientException('Unable to determine state');
            }

The url looks like:

https://example.org/apps/openidconnect/redirect?state=099d67f56a2eada4a215d93b9ba8df6b&session_state=818a6ae5-24a9-42d1-a9d8-139d69b772db&code=9a888677-0539-4f40-8046-8af8a3a465dd.818a6ae5-24a9-42d1-a9d8-139d69b772db.cf62e627-a7a1-4c9d-853a-9f43e18126a6

The state variable is present in the url.

Which means that, somehow, the state KeyCloak returns is not the state that OwnCloud expects.

Any ideas on how that could happen?

1 Like

Finally stumbled across the solution here: Unable to determine state after update to php 7.4 · Issue #157 · owncloud/openidconnect · GitHub

So my working config looks like:

$CONFIG['http.cookie.samesite'] = 'None';
$CONFIG['openid-connect'] =
  [
    'autoRedirectOnLoginPage' => false,
    'client-id' => 'cloud_example_org',
    'client-secret' => trim(file_get_contents('/run/secrets/openid_client_secret')),
    'loginButtonName' => 'keycloakhostname',
    'mode' => 'sub',
    'provider-url' => 'https://keycloakhostname/auth/realms/raygunhosting',
    'search-attribute' => 'sub',
    'scopes' => ['openid'],
    'auto-provision' =>
      [
        'enabled' => true,
        'mode' => 'userid',
        'search-attribute' => 'userid',
        'email-claim' => 'email',
      ],
  ];
3 Likes

Thank you for sharing your experience. I’m pretty sure this will help other users as well.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.