Server
Server
Authorization server engine implementing the MCP Authorization subset of OAuth 2.1.
class Server extends \Hazaar\ControllerExtends: Hazaar\Controller
Extend this (normally via Hazaar\Controller\OAuth) to turn an application into an MCP OAuth authorization server. The engine owns protocol mechanics only:
- Hazaar\OAuth\Server::metadata: RFC 8414 metadata document (
/.well-known/oauth-authorization-server) - Hazaar\OAuth\Server::authorize: the authorization code + PKCE front-channel flow (
/authorize) - Hazaar\OAuth\Server::token: the
authorization_codeandrefresh_tokengrants (/token) - Hazaar\OAuth\Server::register: RFC 7591 dynamic client registration (
/register)
How users log in and how consent is presented are the application's responsibility, delegated through two hooks:
- Hazaar\OAuth\Server::authenticatedUser — defaults to delegating to Hazaar\Auth\Adapter, override if the app resolves the current user differently.
- Hazaar\OAuth\Server::consent — abstract; the app implements the consent UI and returns a Hazaar\OAuth\ConsentDecision.
Persistence is delegated to three storage interfaces the app binds via config (oauth.server.clients, oauth.server.codes, oauth.server.refresh_tokens): Hazaar\OAuth\Interface\ClientRepository, Hazaar\OAuth\Interface\AuthorizationCodeStore, Hazaar\OAuth\Interface\RefreshTokenStore. Ready-to-use DBI-backed implementations are provided under Hazaar\OAuth\Store\DBI.
Access tokens are JWTs (RS256 by default) minted and verified with the existing Hazaar\Auth\Session\Backend\JWT machinery — configure signing/verification key material under oauth.server.jwt exactly as you would for auth.jwt. Refresh tokens are deliberately not JWTs: they are opaque, store-backed, and rotated on every use, because — unlike access tokens — they are only ever presented back to this server and must be revocable.
Properties
config
protected Options $configType: Hazaar\OAuth\Server\Options
clients
protected ClientRepository $clientsType: Hazaar\OAuth\Interface\ClientRepository
codes
protected AuthorizationCodeStore $codesType: Hazaar\OAuth\Interface\AuthorizationCodeStore
refreshTokens
protected RefreshTokenStore $refreshTokensType: Hazaar\OAuth\Interface\RefreshTokenStore
jwt
private JWT $jwtType: Hazaar\Auth\Session\Backend\JWT
Methods
__construct
public __construct(Request $request): voidParameters
| Parameter | Type | Description |
|---|---|---|
$request | Hazaar\Application\Request |
metadata
RFC 8414 authorization server metadata document.
public metadata(): Response\JSONReturns: Hazaar\Controller\Response\JSON
Mount at /.well-known/oauth-authorization-server.
authorize
The authorization code + PKCE front-channel flow.
public authorize(): ResponseReturns: Hazaar\Controller\Response
Mount at /authorize (GET, and POST for consent form resubmission).
token
The authorization_code and refresh_token token grants.
public token(): Response\JSONReturns: Hazaar\Controller\Response\JSON
Mount at /token (POST).
register
RFC 7591 dynamic client registration.
public register(): Response\JSONReturns: Hazaar\Controller\Response\JSON
Mount at /register (POST).
loadConfig
Loads the oauth.server configuration section.
protected loadConfig(): arrayReturns: array
Override to source configuration some other way (e.g. in tests, to inject fake stores or key material directly instead of round-tripping through app config files).
authenticatedUser
Resolves the currently authenticated user for the /authorize step.
protected authenticatedUser(): ?stringReturns: string
Defaults to delegating to Hazaar\Auth\Adapter: the app's own login flow is whatever populates that adapter's session (username/password, SSO, etc.) — this component only cares whether a user is authenticated. Override if the app resolves identity some other way.
redirectToLogin
Redirects an unauthenticated user to the application's login page.
protected redirectToLogin(): ResponseReturns: Hazaar\Controller\Response
The original /authorize request (including all query parameters) is preserved in a return_to parameter, so the app's login flow can bounce the user straight back once they've authenticated.
consent
protected consent(Client $client, array $scope, string $userIdentity): ConsentDecisionReturns: Hazaar\OAuth\ConsentDecision
Parameters
| Parameter | Type | Description |
|---|---|---|
$client | Hazaar\OAuth\Client | |
$scope | array | |
$userIdentity | string |
issueAccessToken
Mints a signed JWT access token via the shared Hazaar\Auth\Session\Backend\JWT machinery.
protected issueAccessToken(string $userIdentity, string $clientId, array $scope, ?string $resource): ExpiringTokenReturns: Hazaar\Auth\ExpiringToken
Parameters
| Parameter | Type | Description |
|---|---|---|
$userIdentity | string | |
$clientId | string | |
$scope | array | |
$resource | string |
issueRefreshToken
Issues a new opaque, store-backed refresh token.
protected issueRefreshToken(string $userIdentity, string $clientId, array $scope, ?string $resource): RefreshTokenReturns: Hazaar\OAuth\RefreshToken
Parameters
| Parameter | Type | Description |
|---|---|---|
$userIdentity | string | |
$clientId | string | |
$scope | array | |
$resource | string |
grantAuthorizationCode
private grantAuthorizationCode(array $body): arrayReturns: array
Parameters
| Parameter | Type | Description |
|---|---|---|
$body | array |
grantRefreshToken
private grantRefreshToken(array $body): arrayReturns: array
Parameters
| Parameter | Type | Description |
|---|---|---|
$body | array |
authenticateClient
Authenticates the client presenting a /token request.
private authenticateClient(array $body): ClientReturns: Hazaar\OAuth\Client
Accepts client_secret_basic (HTTP Basic authorization header) or client_secret_post (client_id/client_secret in the body). Public clients (token_endpoint_auth_method === 'none') are identified by client_id alone and rely on PKCE instead.
Parameters
| Parameter | Type | Description |
|---|---|---|
$body | array |
verifyPKCE
private verifyPKCE(string $codeChallenge, string $codeVerifier): boolReturns: bool
Parameters
| Parameter | Type | Description |
|---|---|---|
$codeChallenge | string | |
$codeVerifier | string |
parseScope
private parseScope(?string $scope): arrayReturns: array
Parameters
| Parameter | Type | Description |
|---|---|---|
$scope | string |
bodyParams
private bodyParams(): arrayReturns: array
requireParam
private requireParam(string $key): stringReturns: string
Parameters
| Parameter | Type | Description |
|---|---|---|
$key | string |
redirectWithParams
private redirectWithParams(string $redirectUri, array $params): ResponseReturns: Hazaar\Controller\Response
Parameters
| Parameter | Type | Description |
|---|---|---|
$redirectUri | string | |
$params | array |
issuer
private issuer(): stringReturns: string
endpointURL
private endpointURL(string $path): stringReturns: string
Parameters
| Parameter | Type | Description |
|---|---|---|
$path | string |
resolveStore
Instantiates a store bound via config, which may be a class-string (constructed with the
private resolveStore(object|string $binding, string $interface, array $options): objectReturns: object
given options) or an already-built instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
$binding | object | string |
$interface | string | |
$options | array |
Generated by Hazaar API Doc Generator on Sun, 23 Aug 2026 10:49:43 +0000