检查 Restler API 框架上的标头授权

发布于 2024-12-11 04:02:23 字数 559 浏览 0 评论 0原文

我想扩展 Restler 以检查是否通过了自定义标头授权的有效值。我在解决这个问题时遇到了麻烦,我尝试了这个,但没有机会:

class AuthenticateMe implements iAuthenticate() {

function __isAuthenticated() {
    //return isset($_SERVER['HTTP_AUTH_KEY']) && $_SERVER['HTTP_AUTH_KEY']==AuthenticateMe::KEY ? TRUE : FALSE;
    $headers = apache_request_headers();
    foreach ($headers as $header => $value) {
        if($header == "Authorization") {
            return TRUE;
        } else {
            //return FALSE;
            throw new RestException(404);
        }
    }
}
}

I want to extend Restler to check if a valid value of custom header Authorization was passed. I am having trouble in getting around the fix, I tried this, but no chance:

class AuthenticateMe implements iAuthenticate() {

function __isAuthenticated() {
    //return isset($_SERVER['HTTP_AUTH_KEY']) && $_SERVER['HTTP_AUTH_KEY']==AuthenticateMe::KEY ? TRUE : FALSE;
    $headers = apache_request_headers();
    foreach ($headers as $header => $value) {
        if($header == "Authorization") {
            return TRUE;
        } else {
            //return FALSE;
            throw new RestException(404);
        }
    }
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一绘本一梦想 2024-12-18 04:02:23

让我快速修复您的自定义身份验证标头示例,

class HeaderAuth implements iAuthenticate{
    function __isAuthenticated(){
        //we are only looking for a custom header called 'Auth'
        //but $_SERVER prepends HTTP_ and makes it all uppercase
        //thats why we need to look for 'HTTP_AUTH' instead
        //also do not use header 'Authorization'. It is not
        //included in PHP's $_SERVER variable
        return isset($_SERVER['HTTP_AUTH']) && $_SERVER['HTTP_AUTH']=='password';
    }
}

我已经对其进行了测试以确保其有效!

以下是如何使其与 Authorization 标头一起工作,它仅适用于 apache 服务器

 class Authorization implements iAuthenticate{
    function __isAuthenticated(){
        $headers =  apache_request_headers();
        return isset($headers['Authorization']) && $headers['Authorization']=='password';
    }
}

我发现 PHP 将 Authorization 标头转换为 $_SERVER['PHP_AUTH_DIGEST']$_SERVER['PHP_AUTH_USER']$_SERVER['PHP_AUTH_PW'] 取决于类型auth 请求(摘要或基本),我们可以使用以下 .htaccess 文件来启用 $_SERVER['HTTP_AUTHORIZATION'] 标头

DirectoryIndex index.php

DirectoryIndex index.php
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ index.php [QSA,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [QSA,L]
    RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
</IfModule>

重要部分是 RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]

现在我们的示例可以简化为:

class Authorization implements iAuthenticate{
    function __isAuthenticated(){
        return isset($_SERVER['HTTP_AUTHORIZATION']) && $_SERVER['HTTP_AUTHORIZATION']=='password';
    }
}

Let me quickly fix your custom auth header example

class HeaderAuth implements iAuthenticate{
    function __isAuthenticated(){
        //we are only looking for a custom header called 'Auth'
        //but $_SERVER prepends HTTP_ and makes it all uppercase
        //thats why we need to look for 'HTTP_AUTH' instead
        //also do not use header 'Authorization'. It is not
        //included in PHP's $_SERVER variable
        return isset($_SERVER['HTTP_AUTH']) && $_SERVER['HTTP_AUTH']=='password';
    }
}

I have tested it to make sure it works!

Here is how to make it work with Authorization header, it works only on apache servers

 class Authorization implements iAuthenticate{
    function __isAuthenticated(){
        $headers =  apache_request_headers();
        return isset($headers['Authorization']) && $headers['Authorization']=='password';
    }
}

I figured out that PHP converts Authorization header into $_SERVER['PHP_AUTH_DIGEST'] or $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'] depending on the type of auth request (digest or basic), we can use the following .htaccess file to enable the $_SERVER['HTTP_AUTHORIZATION'] header

DirectoryIndex index.php

DirectoryIndex index.php
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ index.php [QSA,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [QSA,L]
    RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
</IfModule>

important part is RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]

Now our example can be simplified to:

class Authorization implements iAuthenticate{
    function __isAuthenticated(){
        return isset($_SERVER['HTTP_AUTHORIZATION']) && $_SERVER['HTTP_AUTHORIZATION']=='password';
    }
}
韬韬不绝 2024-12-18 04:02:23

标头身份验证

有三种方法可以实现

  1. HTTP 基本身份验证
  2. HTTP 摘要身份验证
  3. 使用自定义 HTTP 标头自行推出

您可以从 PHP 手册

Restler 1.0 有一个摘要式身份验证示例。我进行了修改以使其与 Restler 2.0 一起使用

class DigestAuthentication implements iAuthenticate
{
    public $realm = 'Restricted API';
    public static $user;
    public $restler;


    public function __isAuthenticated()
    {
        //user => password hardcoded for convenience
        $users = array('admin' => 'mypass', 'guest' => 'guest');
        if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
            header('HTTP/1.1 401 Unauthorized');
            header('WWW-Authenticate: Digest realm="'.$this->realm.'",qop="auth",nonce="'.
            uniqid().'",opaque="'.md5($this->realm).'"');
            throw new RestException(401, 'Digest Authentication Required');
        }

        // analyze the PHP_AUTH_DIGEST variable
        if (!($data = DigestAuthentication::http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
        !isset($users[$data['username']]))
        {
            throw new RestException(401, 'Wrong Credentials!');
        }


        // generate the valid response
        $A1 = md5($data['username'] . ':' . $this->realm . ':' . $users[$data['username']]);
        $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
        $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

        if ($data['response'] != $valid_response)
        {
            throw new RestException(401, 'Wrong Credentials!');
        }
        // ok, valid username & password
        DigestAuthentication::$user=$data['username'];
        return true;
    }

    /**
     * Logs user out of the digest authentication by bringing the login dialog again
     * ignore the dialog to logout
     *
     * @url GET /user/login
     * @url GET /user/logout
     */
    public function logout()
    {
        header('HTTP/1.1 401 Unauthorized');
        header('WWW-Authenticate: Digest realm="'.$this->realm.'",qop="auth",nonce="'.
        uniqid().'",opaque="'.md5($this->realm).'"');
        die('Digest Authorisation Required');
    }


    // function to parse the http auth header
    private function http_digest_parse($txt)
    {
        // protect against missing data
        $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
        $data = array();
        $keys = implode('|', array_keys($needed_parts));

        preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

        foreach ($matches as $m) {
            $data[$m[1]] = $m[3] ? $m[3] : $m[4];
            unset($needed_parts[$m[1]]);
        }

        return $needed_parts ? false : $data;
    }
}

Header Authentication

there are three ways to do it

  1. HTTP Basic Authentication
  2. HTTP Digest Authentication
  3. Roll our own using custom HTTP headers

You can read more from PHP Manual

Restler 1.0 had a Digest Authentication example. I've modified to make it work with Restler 2.0

class DigestAuthentication implements iAuthenticate
{
    public $realm = 'Restricted API';
    public static $user;
    public $restler;


    public function __isAuthenticated()
    {
        //user => password hardcoded for convenience
        $users = array('admin' => 'mypass', 'guest' => 'guest');
        if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
            header('HTTP/1.1 401 Unauthorized');
            header('WWW-Authenticate: Digest realm="'.$this->realm.'",qop="auth",nonce="'.
            uniqid().'",opaque="'.md5($this->realm).'"');
            throw new RestException(401, 'Digest Authentication Required');
        }

        // analyze the PHP_AUTH_DIGEST variable
        if (!($data = DigestAuthentication::http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
        !isset($users[$data['username']]))
        {
            throw new RestException(401, 'Wrong Credentials!');
        }


        // generate the valid response
        $A1 = md5($data['username'] . ':' . $this->realm . ':' . $users[$data['username']]);
        $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
        $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

        if ($data['response'] != $valid_response)
        {
            throw new RestException(401, 'Wrong Credentials!');
        }
        // ok, valid username & password
        DigestAuthentication::$user=$data['username'];
        return true;
    }

    /**
     * Logs user out of the digest authentication by bringing the login dialog again
     * ignore the dialog to logout
     *
     * @url GET /user/login
     * @url GET /user/logout
     */
    public function logout()
    {
        header('HTTP/1.1 401 Unauthorized');
        header('WWW-Authenticate: Digest realm="'.$this->realm.'",qop="auth",nonce="'.
        uniqid().'",opaque="'.md5($this->realm).'"');
        die('Digest Authorisation Required');
    }


    // function to parse the http auth header
    private function http_digest_parse($txt)
    {
        // protect against missing data
        $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
        $data = array();
        $keys = implode('|', array_keys($needed_parts));

        preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

        foreach ($matches as $m) {
            $data[$m[1]] = $m[3] ? $m[3] : $m[4];
            unset($needed_parts[$m[1]]);
        }

        return $needed_parts ? false : $data;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文