Skip to content

r3h6/TYPO3.EXT.oauth2_server

Repository files navigation

OAuth2 Server

OAuth2 server for TYPO3 based on PHP League's OAuth2 Server.

Features:

  • Supports all grant types from PHP League's OAuth2 Server
  • Scopes can be limited to clients
  • Grant types can be limited to clients
  • Can be used to protect API's from other extensions

Installation

Only composer supported!

$ composer require r3h6/oauth2-server

Webserver

Note that depending on the webserver and PHP integration therein you might need some additional configuration.

Specifically Apache + CGI (PHP-FPM) needs additional vhost/htaccess configuration in order to have proper authorization header handling.

SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

See also: https://symfony.com/doc/current/setup/web_server_configuration.html#using-mod-proxy-fcgi-with-apache-2-4

Integration

Create your own public and private keys.
Use the provided key pair only for development.

You must explicit enable the OAuth2 server in your site configuration yaml by adding at least following configuration:

oauth2: []

For the authorization code grant you must create a frontend login and a consent page.
This extension provides a TypoScript setup with a basic design.

Create a sysfolder and add a client record.

Page tree with new client

Endpoints

Endpoint Description
/oauth2/authorize GET = Start authorization, POST = Accept, DELETE = Deny
/oauth2/token Issues token
/oauth2/revoke Revokes an access token

Configuration

oauth2:
  # Optional. Defaults to 'true'
  enabled: true

  # Path to private key
  # Type: string
  privateKey: 'EXT:oauth2_server/Resources/Private/Keys/private.key'

  # Path to public key
  # Type: string
  publicKey: 'EXT:oauth2_server/Resources/Private/Keys/public.key'

  # Access token lifetime
  # Type: string
  accessTokensExpireIn: 'P1M'

  # Refresh token lifetime
  # Type: string
  refreshTokensExpireIn: 'P1M'

  # Requires all public clients to provide a PKCE code challenge
  # See https://oauth2.thephpleague.com/upgrade-guide/
  # Type: boolean
  requireCodeChallengeForPublicClients: true

  # Page uid with "Oauth2: Consent" plugin
  # Type: int
  consentPageUid: 0

  # Page uid for frontend login (otherwise users are redirected to the root page)
  # Type: int
  loginPageUid: 0

  # Scopes
  # Type: array
  scopes:
    - scope1
    - { identifier: scope2, description: 'Description or LLL path', consent: true }

  # Configuration for protected resources
  resources:

    # Resource name
    my_resource:

      # Resource route, string, a regex matching the request path
      # Type: string
      path: /rest/.*

      # Defines whether authorization is required
      # Note: A given authorization header is still processed even if this is disabled.
      #       This is great for APIs with optional authentication
      # Type: boolean
      authorization: true

      # Resource methods (optional)
      # Type: string|array
      methods: POST|GET

      # Resource target (optional)
      # Type: string
      target: Controller::action

      # Firewall rule, checks if a user is authenticated (optional)
      # Type: boolean
      authenticated: false

      # Firewall rule, check if client ip matches given pattern (optional)
      # Type: string
      ip: '127.*'

      # Firewall rule, check if request is using https (optional)
      # Type: boolean
      https: true

      # Firewall rule, check if access token has at least one of the scopes (optional)
      # Type: string|array
      scope: 'read|write'

      # Firewall rule, check if access token has all scopes (optional)
      # Type: string|array
      scope: 'read,write'

Protecting resources from Extbase plugins.

Extbase-plugins with routing can still be called through query parameters.
Such requests bypass the request validation of this extension.
You should therefore make some htaccess rules denying such request,
implement the request validation by yourself or
use the ExtbaseGuard to check if the request passed the validation.

class ExtbaseController extends ActionController
{
    /**
     * @var \R3H6\Oauth2Server\Security\ExtbaseGuard
     * @TYPO3\CMS\Extbase\Annotation\Inject
     */
    protected $guard;

    public function initializeAction()
    {
        $this->guard->checkAccess($GLOBALS['TYPO3_REQUEST'], 'my_resource', $this->response); //v10
        $this->guard->checkAccess($GLOBALS['TYPO3_REQUEST'], 'my_resource'); //v11
    }
}

Middlewares

This extension adds several middlewares to the stack. They must be executed in the expected order in order to work correctly.

...
typo3/cms-frontend/site
...
r3h6/oauth2-server/configuration
r3h6/oauth2-server/routing
r3h6/oauth2-server/authentication
...
typo3/cms-frontend/authentication
...
r3h6/oauth2-server/firewall
r3h6/oauth2-server/dispatcher
...
typo3/cms-frontend/base-redirect-resolver
...

Credits

  • Marco Huber for handing over the extension key and sharing his ideas