Skip to content

Commit

Permalink
Fixed some more imports, added examples of customizing auth failures
Browse files Browse the repository at this point in the history
  • Loading branch information
davidbyoung committed Feb 15, 2025
1 parent cad7283 commit 6c27a9f
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 38 deletions.
6 changes: 2 additions & 4 deletions application-builders.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,7 @@ Customizing your [authority](authorization.md) is also simple.
```php
use Aphiria\Application\IApplicationBuilder;
use Aphiria\Authorization\AuthorizationPolicy;
use Aphiria\Authorization\Requirements\RolesRequirement;
use Aphiria\Authorization\Requirements\RolesRequirementHandler;
use Aphiria\Authorization\Requirements\{RolesRequirement, RolesRequirementHandler};
use Aphiria\Framework\Application\AphiriaModule;

final class GlobalModule extends AphiriaModule
Expand Down Expand Up @@ -461,8 +460,7 @@ final class GlobalModule extends AphiriaModule
All that's left is to start using the component from a module:

```php
use Aphiria\Application\IApplicationBuilder;
use Aphiria\Application\IModule;
use Aphiria\Application\{IApplicationBuilder, IModule};
use App\SymfonyRouterComponent;
use Symfony\Component\Routing\Route;

Expand Down
38 changes: 29 additions & 9 deletions authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,7 @@ This will build a primary identity with the specified claims. The following flu
If you want to build multiple identities for your principal, you can.

```php
use Aphiria\Security\IdentityBuilder;
use Aphiria\Security\PrincipalBuilder;
use Aphiria\Security\{IdentityBuilder, PrincipalBuilder};

$user = new PrincipalBuilder('example.com')
->withIdentity(function (IdentityBuilder $identity) {
Expand Down Expand Up @@ -299,8 +298,7 @@ final class GlobalModule extends AphiriaModule
You can use `AuthenticationBuilder::withScheme()` to register a default scheme:

```php
use Aphiria\Authentication\AuthenticationScheme;
use Aphiria\Authentication\AuthenticatorBuilder;
use Aphiria\Authentication\{AuthenticationScheme, AuthenticatorBuilder};
use App\MyCookieHandler;

$authenticator = new AuthenticatorBuilder()
Expand Down Expand Up @@ -401,8 +399,7 @@ final class GlobalModule extends AphiriaModule
Let's register this scheme with `AuthenticationBuilder`:

```php
use Aphiria\Authentication\AuthenticationScheme;
use Aphiria\Authentication\AuthenticatorBuilder;
use Aphiria\Authentication\{AuthenticationScheme, AuthenticatorBuilder};
use Aphiria\Authentication\Schemes\BasicAuthenticationOptions;

$authenticator = new AuthenticatorBuilder()
Expand Down Expand Up @@ -462,8 +459,7 @@ final class GlobalModule extends AphiriaModule
<div class="context-library">

```php
use Aphiria\Authentication\AuthenticationScheme;
use Aphiria\Authentication\AuthenticatorBuilder;
use Aphiria\Authentication\{AuthenticationScheme, AuthenticatorBuilder};
use Aphiria\Authentication\Schemes\CookieAuthenticationOptions;
use Aphiria\Net\Http\Headers\SameSiteMode;

Expand Down Expand Up @@ -522,9 +518,33 @@ if (!$result->passed) {
$user = $result->user;
```

> **Note:** If you pass in a string failure message, `$result->failure` will return an instance of `Exception` with that message.
<h2 id="customizing-authentication-failure-responses">Customizing Authentication Failure Responses</h2>

By default, when authentication in the `Authenticate` middleware fails, `challenge()` will be called on the same scheme handler that we attempted to authenticate with. Most handlers' `challenge()` methods will set the status code to 401 or redirect you to the login page, depending on the implementation. If you'd like to customize this, you can extend `Authenticate` and override `handleFailedAuthenticationResult()` to return a response.
By default, when authentication in the `Authenticate` middleware fails, `challenge()` will be called on the same scheme handler that we attempted to authenticate with. Most handlers' `challenge()` methods will set the status code to 401 or redirect you to the login page, depending on the implementation. If you'd like to customize this, you can extend `Authenticate` and override `handleFailedAuthenticationResult()` to return a response. Let's look at an example:

```php
use Aphiria\Authentication\AuthenticationResult;
use Aphiria\Authentication\Middleware\Authenticate as BaseAuthenticate;
use Aphiria\Net\Http\{HttpStatusCode, IRequest, IResponse, Response, StringBody};

final class Authenticate extends BaseAuthenticate
{
protected function handleFailedAuthenticationResult(
IRequest $request,
AuthenticationResult $failedAuthenticationResult
): IResponse {
// Let's return a response with body "You are not logged in"
$response = new Response(HttpStatusCode::Unauthorized);
$response->body = new StringBody('You are not logged in');

return $response;
}
}
```

Then, use your custom `Authenticate` middleware instead of the built-in one.

<div class="context-framework">

Expand Down
55 changes: 40 additions & 15 deletions authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ final class ArticleController extends Controller
Here's the identical functionality, just using `IAuthority` instead of an attribute:

```php
use Aphiria\Authorization\AuthorizationPolicy;
use Aphiria\Authorization\IAuthority;
use Aphiria\Authorization\{AuthorizationPolicy, IAuthority};
use Aphiria\Authorization\RequirementHandlers\RolesRequirement;
use Aphiria\Net\Http\IResponse;
use App\Article;
Expand Down Expand Up @@ -96,10 +95,8 @@ Next, let's create a handler that checks this requirement:
```php
namespace App;

use Aphiria\Authorization\AuthorizationContext;
use Aphiria\Authorization\IAuthorizationRequirementHandler;
use Aphiria\Security\ClaimType;
use Aphiria\Security\IPrincipal;
use Aphiria\Authorization\{AuthorizationContext, IAuthorizationRequirementHandler};
use Aphiria\Security\{ClaimType, IPrincipal};

final class MinimumAgeRequirementHandler implements IAuthorizationRequirementHandler
{
Expand Down Expand Up @@ -166,8 +163,7 @@ final class GlobalModule extends AphiriaModule
<div class="context-library">

```php
use Aphiria\Authorization\AuthorityBuilder;
use Aphiria\Authorization\AuthorizationPolicy;
use Aphiria\Authorization\{AuthorityBuilder, AuthorizationPolicy};
use App\{MinimumAgeRequirement, MinimumAgeRequirementHandler};

$authority = new AuthorityBuilder()
Expand Down Expand Up @@ -247,10 +243,8 @@ Next, let's define a handler for this requirement:
```php
namespace App;

use Aphiria\Authorization\AuthorizationContext;
use Aphiria\Authorization\IAuthorizationRequirementHandler;
use Aphiria\Security\ClaimType;
use Aphiria\Security\IPrincipal;
use Aphiria\Authorization\{AuthorizationContext, IAuthorizationRequirementHandler};
use Aphiria\Security\{ClaimType, IPrincipal};
use App\Comment;

final class AuthorizedDeleterRequirementHandler implements IAuthorizationRequirementHandler
Expand Down Expand Up @@ -328,8 +322,7 @@ final class GlobalModule extends AphiriaModule
<div class="context-library">

```php
use Aphiria\Authorization\AuthorityBuilder;
use Aphiria\Authorization\AuthorizationPolicy;
use Aphiria\Authorization\{AuthorityBuilder, AuthorizationPolicy};
use App\{AuthorizedDeleterRequirement, AuthorizedDeleterRequirementHandler};

$authority = new AuthorityBuilder()
Expand Down Expand Up @@ -388,4 +381,36 @@ if (!$authorizationResult->passed) {

<h2 id="customizing-failed-authorization-responses">Customizing Failed Authorization Responses</h2>

By default, authorization done in the `Authorize` middleware invokes [`IAuthenticator::challenge()`](authentication.md) when a user is not authenticated, and `IAuthenticator::forbid()` when they are not authorized. If you would like to customize these responses, simply override `Authorize::handleUnauthenticatedUser()` and `Authorize::handleFailedAuthorizationResult()`.
By default, authorization done in the `Authorize` middleware invokes [`IAuthenticator::challenge()`](authentication.md) when a user is not authenticated, and `IAuthenticator::forbid()` when they are not authorized. If you would like to customize these responses, simply override `Authorize::handleUnauthenticatedUser()` and `Authorize::handleFailedAuthorizationResult()`. Let's look at an example:

```php
use Aphiria\Authorization\{AuthorizationPolicy, AuthorizationResult};
use Aphiria\Authorization\Middleware\Authorize as BaseAuthorize;
use Aphiria\Net\Http\{HttpStatusCode, IRequest, IResponse, Response, StringBody};

final class Authorize extends BaseAuthorize
{
protected function handleFailedAuthorizationResult(
IRequest $request,
AuthorizationPolicy $policy,
AuthorizationResult $authorizationResult
): IResponse {
// Let's return a response with body "You are not authorized"
$response = new Response(HttpStatusCode::Forbidden);
$response->body = new StringBody('You are not authorized');

return $response;
}

protected function handleUnauthenticatedUser(IRequest $request, AuthorizationPolicy $policy): IResponse
{
// Let's return a response with body "You are not logged in"
$response = new Response(HttpStatusCode::Unauthorized);
$response->body = new StringBody('You are not logged in');

return $response;
}
}
```

Then, use your custom `Authorize` middleware instead of the built-in one.
3 changes: 1 addition & 2 deletions controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ Setting headers is simple, too:

```php
use Aphiria\Api\Controllers\Controller;
use Aphiria\Net\Http\Headers;
use Aphiria\Net\Http\IResponse;
use Aphiria\Net\Http\{Headers, IResponse};
use App\IUserService;

final class UserController extends Controller
Expand Down
9 changes: 3 additions & 6 deletions routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,7 @@ use Aphiria\Application\IApplicationBuilder;
use Aphiria\Authentication\Attributes\Authenticate;
use Aphiria\Framework\Application\AphiriaModule;
use Aphiria\Routing\Middleware\MiddlewareBinding;
use Aphiria\Routing\RouteCollectionBuilder;
use Aphiria\Routing\RouteGroupOptions;
use Aphiria\Routing\{RouteCollectionBuilder, RouteGroupOptions};
use App\{CourseController, MyConstraint};

final class CourseModule extends AphiriaModule
Expand Down Expand Up @@ -672,8 +671,7 @@ final class CourseModule extends AphiriaModule

```php
use Aphiria\Routing\Middleware\MiddlewareBinding;
use Aphiria\Routing\RouteCollectionBuilder;
use Aphiria\Routing\RouteGroupOptions;
use Aphiria\Routing\{RouteCollectionBuilder, RouteGroupOptions};
use App\{Authenticate, CourseController, MyConstraint};

$routes->group(
Expand Down Expand Up @@ -1362,8 +1360,7 @@ To enable caching, pass in an `IRouteCache` (`FileRouteCache` is provided) to th

```php
use Aphiria\Routing\Caching\FileRouteCache;
use Aphiria\Routing\RouteCollection;
use Aphiria\Routing\RouteRegistrantCollection;
use Aphiria\Routing\{RouteCollection, RouteRegistrantCollection};

$routes = new RouteCollection();
$routeRegistrant = new RouteRegistrantCollection(new FileRouteCache('/tmp/routeCache.txt'));
Expand Down
3 changes: 1 addition & 2 deletions validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ final class UserModule extends AphiriaModule

```php
use Aphiria\Validation\Constraints\{EmailConstraint, RequiredConstraint};
use Aphiria\Validation\ObjectConstraintsRegistryBuilder;
use Aphiria\Validation\Validator;
use Aphiria\Validation\{ObjectConstraintsRegistryBuilder, Validator};
use App\User;

// Set up our validator
Expand Down

0 comments on commit 6c27a9f

Please sign in to comment.