Beispiel #1
0
<?php

// Define used classes.
use lithium\util\collection\Filters;
use lithium\security\Auth;
// Get to the `Auth` instance by filtering the `Dispatcher`
Filters::apply('\\lithium\\action\\Dispatcher', '_callable', function ($self, $params, $chain) {
    $controller = $chain->next($self, $params, $chain);
    Auth::applyFilter('check', function ($self, $params, $chain) {
        $profiler = \Profiler::start('security\\Auth::check');
        $result = $chain->next($self, $params, $chain);
        $profiler->end();
        return $result;
    });
    Auth::applyFilter('set', function ($self, $params, $chain) {
        $profiler = \Profiler::start('security\\Auth::set');
        $result = $chain->next($self, $params, $chain);
        $profiler->end();
        return $result;
    });
    Auth::applyFilter('clear', function ($self, $params, $chain) {
        $profiler = \Profiler::start('security\\Auth::clear');
        $result = $chain->next($self, $params, $chain);
        $profiler->end();
        return $result;
    });
    // Return the controller object.
    return $controller;
});
Auth::applyFilter('check', function ($self, $params, $chain) {
    $result = $chain->next($self, $params, $chain);
    /**
     * `Auth::check` is called in two context
     * 1. With a `Request` object to sign a user in
     * 2. With no arguments to check if the current user is signed in
     *
     * We only need to check in the first case.
     */
    if (isset($params['credentials']) && $params['credentials']) {
        $request = $params['credentials'];
        $signature = $request->env('HTTP_X_SIGNATURE');
        $username = $request->env('HTTP_X_USERNAME');
        if ($username && $signature) {
            /**
             * Find the username the request is attempted to be made for
             * The user object is needed because it holds the secret key
             * we need to be able to regenerate the signature
             */
            $user = Users::first(array('conditions' => compact('username')));
            if (!$user) {
                throw new \Exception("Invalid user {$username}");
            }
            /**
             * GET and POST/PUT passes payload differently, this either `query` or `data`
             * Also doing rewriting can mean that the `url` GET param is added
             */
            $signData = $request->is('get') ? array_diff_key($request->query, array('url' => 'sodoff')) : $request->data;
            /**
             * Prepend the request path so all requests with no data
             * does not get the same key
             */
            array_unshift($signData, $request->env('base'));
            if ($signature === $user->sign($signData)) {
                return true;
            } else {
                throw new \Exception("Signature match failed in signed request");
            }
        }
    }
    return $result;
});