PHPackages                             egroupware/openid - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. egroupware/openid

ActiveEgroupware-app[Authentication &amp; Authorization](/categories/authentication)

egroupware/openid
=================

EGroupware OpenID Connect / OAuth2 server

26.7.20260724(1mo ago)1328.9k31GPL-2.0-or-laterPHP

Since Jul 16Pushed 3w ago2 watchersCompare

[ Source](https://github.com/EGroupware/openid)[ Packagist](https://packagist.org/packages/egroupware/openid)[ Docs](https://www.egroupware.org/)[ RSS](/packages/egroupware-openid/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (57)Versions (136)Used By (1)

OpenID Connect and OAuth2 server for EGroupware
===============================================

[](#openid-connect-and-oauth2-server-for-egroupware)

2026 rewrite against current upstream releases
----------------------------------------------

[](#2026-rewrite-against-current-upstream-releases)

This app used to vendor its own, long-outdated copies of `league/oauth2-server` (7.4.0), `steverhoades/oauth2-openid-connect-server` (1.3.0), `lcobucci/jwt` (3.4.6) and `slim/slim`(3.13.0, EOL) in its own `vendor/` directory, with several upstream classes copy-pasted into `EGroupware\OpenID\*` and patched just to keep running on PHP 8.

It has now been rewritten on top of current upstream releases (`league/oauth2-server` ^9.4, `steverhoades/oauth2-openid-connect-server` ^3.0.1, `lcobucci/jwt` ^5.6, `slim/slim` ^4.15), reusing the existing DB-backed storage layer (Repositories/Entities) unchanged wherever the new interfaces allow it. The app's own `vendor/` directory is gone; it now shares EGroupware's main `vendor/` tree like every other app, which also fixed a real bug (see below).

- [`doc/UPSTREAM-OVERRIDES.md`](doc/UPSTREAM-OVERRIDES.md) catalogs every class that forks, patches or extends upstream code, why, and what changed in the rewrite - the API migration notes there are the place to look when touching `AuthorizationServer.php`, the `Grant/*`overrides, `IdTokenResponse.php`, `ClaimExtractor.php` or the JWT signing/validation code.
- `tests/` has a new black-box HTTP contract test suite (PHPUnit + Guzzle against the real `endpoint.php`, following `api/tests/CalDAVTest.php`'s conventions) covering all grants (client\_credentials, password, refresh\_token, authorization\_code, implicit), `/userinfo`, `/introspect`, `/jwks` and OpenID Discovery. Run it from the main repo root with: `EGW_URL="http:///egroupware" vendor/bin/phpunit -c doc/phpunit.xml openid/tests`
- Sharing one `vendor/` tree fixed a real bug: `egroupware/status`'s Jitsi backend and this app's `Token.php` (used by rocketchat's SSO integration) used to each load their own, differently versioned copy of `lcobucci/jwt` - since PHP resolves classes globally by name, whichever package's autoloader ran first for a given request "won", and lcobucci/jwt 3.4.6's `class_alias()`-based compat layer made this a permanent, order-dependent landmine. There is now exactly one `lcobucci/jwt` (5.6) in the whole process.

Supported endpoints and token issuer
------------------------------------

[](#supported-endpoints-and-token-issuer)

- Authorization:
- Token: [https://example.org/egroupware/openid/endpoint.php/access\_token](https://example.org/egroupware/openid/endpoint.php/access_token)
- Token Introspection:
- User information:
- Public key:
- Configuration:
- Issuer:

> Replace example.org with the full qualified domain-name your EGroupware server uses.

Supported Grants:
-----------------

[](#supported-grants)

- Authorization Code: user authorized access and get auth-code, server requests access-token via backchannel
- Refresh Token: token to refresh access-token after it's expired
- Client Credentials: server requests access-token without further authorization
- Implicit: user authorized access and get access-token and auth-code, server requests own access-token via backchannel
- Password Credential: other server checks username/password of EGroupware user (not recommended any more, as other server gets the password!)

Client configuration in EGroupware
----------------------------------

[](#client-configuration-in-egroupware)

> Go to: Admin &gt; Applications &gt; OpenID / OAuth2 server &gt; Clients

More useful resources
---------------------

[](#more-useful-resources)

- [Integration with various clients](https://github.com/EGroupware/egroupware/wiki/OpenID-Connect----OAuth2)
- [OpenID Connect Core 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-core-1_0.html)
- [OpenID Connect Discovery 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html)
- [OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-registration-1_0.html)
- [The PHP League OAuth 2.0 Server](https://github.com/thephpleague/oauth2-server)
- [OpenID Connect Server plugin for The PHP League's OAuth2 Server](https://github.com/steverhoades/oauth2-openid-connect-server)
- [Diagrams of All The OpenID Connect Flows](https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660)
- [Identity, Claims, &amp; Tokens – An OpenID Connect Primer](https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1) in 3 parts

Open tasks:
-----------

[](#open-tasks)

- password grant: record and check failed login attempts like login page (see [user.authentication.failed](https://oauth2.thephpleague.com/authorization-server/events/))
- test with more clients, e.g. [Dovecot](https://wiki2.dovecot.org/PasswordDatabase/oauth2)
- token endpoint must support response\_type=code+id\_token
- allow users to create personal clients
- implement full [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html)
- rewritten against current upstream releases (league/oauth2-server 9.4, steverhoades/oauth2-openid-connect-server 3.0.1, lcobucci/jwt 5.6, slim/slim 4.15), own `vendor/` merged into EGroupware's main vendor tree, black-box HTTP contract test suite added (see "2026 rewrite" above)
- `/introspect` now verifies the requesting client's credentials and requires the client to be the one the token was issued to
- wrong password on login no longer looses the pending oauth request - was a `login.php` bug (dropped `phpgw_forward` on a rejected login), not session data loss; see `tests/AuthorizeWrongPasswordTest.php`
- /.well-known/openid-configuration is supported now
- token endpoint must return nonce of authorization request as claim in id\_token
- fix League OAuth2 server to support multiple response\_type(s), currently it neither [splits response\_type by space](https://github.com/thephpleague/oauth2-server/blob/master/src/Grant/ImplicitGrant.php#L109), nor does it send responses for more then one grant, [see response in this ticket](https://github.com/thephpleague/oauth2-server/issues/903#issuecomment-423891504)
- support response\_type "id\_token" or "token id\_token" containing just an id\_token (JWT) or additional to access\_token an id\_token
- support hyprid flow / response\_type contains additional "code" to also return an auth\_code
- allow to create clients, which behave like an EGroupware App:
    - added to egw\_applications
    - authentication for them works only if user has run-rights for that application
    - an extra defined index-url get's opened as iframe inside EGroupware framework
- UI to view and revoke access- and refresh-tokens
- UI to add clients as admin for all users
- move to a single endpoint.php instead (implicit|auth\_code|client\_credentials|password).php
- add additional [OpenID Connect standard scopes](https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims): profile, address, phone
- implement [OpenID Connect /userinfo endpoint](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
- test with Rocket.Chat, see below for Rocket.Chat custom OAuth configuration
- add [oauth2-server pull request #925](https://github.com/thephpleague/oauth2-server/pull/925) to implement [RFC7662 OAuth 2.0 Token Introspection](https://tools.ietf.org/html/rfc7662) to allow clients to validate tokens
- automatic generation of public key pair and encryption key on first use
- limit clients to certain grant types and scopes (database schema supports that)

Installation
------------

[](#installation)

1. EGroupware master and 19.1 install this app by default: composer install or install-cli.php
2. Install openid app via EGroupware setup

Testing available grants
------------------------

[](#testing-available-grants)

A grant is a method of acquiring an access token. Deciding which grants to use depends on the type of client the end user will be using, and the experience you want for your users.

All examples require to create a client under Admin &gt;&gt; OpenID / OAuth2 server &gt;&gt; Clients with ALL grants first:

```
Name:           oidcdebugger.com
Identifier:     oidcdebugger.com
Secret:         secret
Redirect URI:   https://oidcdebugger.com/debug
Allowed Grants: select all available ones
Limit Scopes:   don't select one
Status:         Active

```

The following test assume your EGroupware installation is reachable under

Testing the client credentials grant
------------------------------------

[](#testing-the-client-credentials-grant)

Send the following cURL request:

```
curl -X "POST" "http://example.org/egroupware/openid/endpoint.php/access_token" \
	-H "Content-Type: application/x-www-form-urlencoded" \
	-H "Accept: 1.0" \
	--data-urlencode "grant_type=client_credentials" \
	--data-urlencode "client_id=oidcdebugger.com" \
	--data-urlencode "client_secret=secret" \
	--data-urlencode "scope=openid email"

```

Testing the password grant
--------------------------

[](#testing-the-password-grant)

Send the following cURL request (replacing &lt;username&gt;/&lt;password&gt; with one valid for your EGroupware!):

```
curl -X "POST" "http://example.org/egroupware/openid/endpoint.php/access_token" \
	-H "Content-Type: application/x-www-form-urlencoded" \
	-H "Accept: 1.0" \
	--data-urlencode "grant_type=password" \
	--data-urlencode "client_id=oidcdebugger.com" \
	--data-urlencode "client_secret=secret" \
	--data-urlencode "username=" \
	--data-urlencode "password=" \
	--data-urlencode "scope=openid email"

```

Testing the implicit grant
--------------------------

[](#testing-the-implicit-grant)

Here we use the OpenID Connect Debugger site, so head to  and add the following data:

```
Authorize URI: http://example.com/egroupware/openid/endpoint.php/authorize
Redirect URI:  https://oidcdebugger.com/debug
Client ID:     oidcdebugger.com
Scope:         openid
Response Type: token
Response Mode: form_post

```

Hit \[Send request\] and you will be redirected to your EGroupware, have to log in, if you not already are, and authorize the request. After that you will be redirected back to the OpenID Connect debuger, which will show if it was successful and in that case the access-token. It should also generate a row in egw\_openid\_access\_token and egw\_open\_id\_access\_token\_scopes table.

Testing the authorization code grant
------------------------------------

[](#testing-the-authorization-code-grant)

Here we use again the OpenID Connect Debugger site for the first step, so head to  and change the URI and Response code as below:

```
Authorize URI: http://example.com/egroupware/openid/endpoint.php/authorize
Redirect URI:  https://oidcdebugger.com/debug
Client ID:     oidcdebugger.com
Scope:         openid
Response Type: code
Response Mode: form_post

```

Hit \[Send request\] and you will be redirected to your EGroupware, have to log in, if you not already are, and authorize the request. After that you will be redirected back to the OpenID Connect debuger, which will show if it was successful and in that case and temporary auth-code which now needs to be exchanged in a 2. step into an access- and a refresh-token.

```
curl -X POST -i http://example.org/egroupware/openid/endpoint.php/access_token \
	-H "Content-Type: application/x-www-form-urlencoded" \
	--data-urlencode "grant_type=authorization_code" \
	--data-urlencode "code=" \
	--data-urlencode "client_id=oidcdebugger.com" \
	--data-urlencode "client_secret=secret" \
	--data-urlencode "redirect_uri=https://oidcdebugger.com/debug"

HTTP/1.1 200 OK
Date: Fri, 05 Apr 2019 06:42:29 GMT
Server: Apache/2.4.38 (Unix) OpenSSL/1.0.2r PHP/7.3.3
X-Powered-By: PHP/7.3.3
pragma: no-cache
cache-control: no-store
Content-Length: 2132
Content-Type: application/json; charset=UTF-8

{"id_token":"","token_type":"Bearer","expires_in":3600,"access_token":"","refresh_token":"
