<?php

header("Content-type: text/html; charset=utf-8");

/*php摘要认证*/

$users = ['dee'=>'123456', 'admin'=>'admin'];
$realm = 'My Website';
$username = validate_digest($realm, $users); print 'Hello, '.htmlentities($username); function validate_digest($realm, $users) { if(! isset($_SERVER['PHP_AUTH_DIGEST'])) {
send_digest($realm);
} //如果摘要无法解析,则会失败
//var_dump($_SERVER['PHP_AUTH_DIGEST']);
//string 'username="你输入的用户名", realm="My Website", nonce="403b875881c55e60a6addd42b904a19c", uri="/php/phpcookbook/web/digest.php", response="080da94742f55682242e9c024529c298", opaque="49918e38b4734f44ffa587368a9e3e1a", qop=auth, nc=00000001, cnonce="d48ffb5a6cd062fc"' (length=253)
$username = parse_digest($_SERVER['PHP_AUTH_DIGEST'], $realm, $users);
if($username === false) {
send_digest($realm);
}
return $username;
} function send_digest($realm) {
http_response_code(401);
// header('HTTP/1.1 Unauthorized');
$nonce = md5(uniqid()); //随机数
$opaque = md5($realm);
header('WWW-Authenticate:Digest realm="'.$realm.'", qop="auth", nonce="'.$nonce.'", opaque="'.$opaque.'"');
//响应头 WWW-Authenticate:Digest realm="My Website", qop="auth", nonce="e0e5319efa00f94b815dbb4b34f88bb0", opaque="49918e38b4734f44ffa587368a9e3e1a"
echo '需要用户名和密码才能继续访问';
exit;
} function parse_digest($digest, $realm, $users) { $digest_info = array(); foreach(array('username', 'uri', 'nonce', 'cnonce', 'response') as $part) {
if(preg_match('/'.$part.'=([\'"]?)(.*?)\1/', $digest, $match)) {
$digest_info[$part] = $match[2];
} else {
return false;
}
} //确保提供了正确的qop
if(preg_match('/qop=auth(,|$)/', $digest)) {
$digest_info['qop'] = 'auth';
} else {
return false;
} //确保提供了合法的nonce数
if(preg_match('/nc=([0-9a-f]{8})(,|$)/', $digest, $match)) {
$digest_info['nc'] = $match[1];
} else{
return false;
} $A1 = $digest_info['username'].':'.$realm.':'.$users[$digest_info['username']];
//var_dump($A1);
//string '你输入的用户名:My Website:' (length=15)
$A2 = $_SERVER['REQUEST_METHOD'].':'.$digest_info['uri'];
//var_dump($A2);
//string 'GET:/php/phpcookbook/web/digest.php' (length=35)
$request_digest = md5(implode(':', [
md5($A1),
$digest_info['nonce'],
$digest_info['nc'],
$digest_info['cnonce'],
$digest_info['qop'],
md5($A2)
])); //比较发送的摘要与我们计算的摘要是否一致
if($request_digest != $digest_info['response']) {
return false;
} //一切正常,返回用户名
return $digest_info['username'];
}

参考:http协议之digest(摘要)认证

<PHP Cookbook,3rd>

PHP 模拟 HTTP 摘要认证(Digest )的更多相关文章

  1. [转]ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)

    本文转自:http://www.cnblogs.com/parry/p/ASPNET_MVC_Web_API_digest_authentication.html 在前一篇文章中,主要讨论了使用HTT ...

  2. ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)

    在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看另一种验证的方式:digest authentication,即摘要认 ...

  3. 安全验证之使用摘要认证(digest authentication)

    安全验证之使用摘要认证(digest authentication) 在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看 ...

  4. asp.net权限认证:摘要认证(digest authentication)

    asp.net权限认证系列 asp.net权限认证:Forms认证 asp.net权限认证:HTTP基本认证(http basic) asp.net权限认证:Windows认证 asp.net权限认证 ...

  5. [转]asp.net权限认证:摘要认证(digest authentication)

    本文转自:http://www.cnblogs.com/lanxiaoke/p/6357501.html 摘要认证简单介绍 摘要认证是对基本认证的改进,即是用摘要代替账户密码,从而防止明文传输中账户密 ...

  6. HTTP认证之摘要认证——Digest(一)

    导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 一.概述 Di ...

  7. HTTP认证之摘要认证——Digest(二)

    导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 在HTTP认证 ...

  8. Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结

    Atitit HTTP认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结 1.1. 最广泛使用的是基本验证 ( ...

  9. ASP.NET Web API 安全验证之摘要(Digest)认证

    在基本认证的方式中,主要的安全问题来自于用户信息的明文传输,而在摘要认证中,主要通过一些手段避免了此问题,大大增加了安全性. 1.客户端匿名的方式请求 (无认证) HTTP/ Unauthorized ...

随机推荐

  1. 执行shell出现bad interpreter

    执行shell出现bad interpreter:No such file or directory linux执行shell出现bad interpreter:No such file or dir ...

  2. ASP.NET MVC中的两个Action之间值的传递--TempData

    一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在一个叫做TempData的Property,它的类型为TempDataDictiona ...

  3. 【krpano】汉化Web VR设置界面

    欢迎加入qq群551278936讨论krpano解密技术以及获取最新软件 krpano 1.19支持了Web VR功能,允许以VR的方式查看全景图,配合上VR设备可以实现VR效果. 在VR方式查看时, ...

  4. 【转】Android中的事件分发和处理

    原文链接:http://www.apkbus.com/home.php?mod=space&uid=705730&do=blog&id=61207 上次跟大家分享了一下自定义V ...

  5. 【YEOMAN】执行yo命令,报EACCES: permission denied, mkdir '/root/.config/configstore'

    基础环境:CentOS7.Nodejs6.0之上,yo:1.8.4 在执行yo初始化webapp时,报错,错误内容如下: Error: EACCES: permission denied, mkdir ...

  6. 使用 lsyncd 本地目录实时备份

    转自 https://segmentfault.com/a/1190000002737213 2.1安装lsyncd # rpm -ivh http://dl.fedoraproject.org/pu ...

  7. SQL Server 临时禁用和启用所有外键约束(高版本向低版本迁移数据)

    --获得禁用所有外键约束的语句 select 'ALTER TABLE [' + b.name + '] NOCHECK CONSTRAINT ' + a.name +';' as 禁用约束 from ...

  8. Java中的位运算

    昨天去面试的时候做到了一道Java的位运算题目,发现有个运算符不懂:">>>",今天特地查了一下,并小结一下常见的位运算符号: ~  按位非(NOT)(一元运算) ...

  9. MVC 好记星不如烂笔头之 ---> 页面压缩GIP

    public class BaseController : Controller { /// <summary> /// Called before the action method i ...

  10. CompletionService/ExecutorCompletionService/线程池/concurrent包

    线程池 线程池的基本思想:线程频繁的创建.销毁会极大地占用系统资源,为了减少系统在创建销毁线程时的开销,线程池应运而生.线程池包括多个已创建的线程,当有任务要在新线程中执行时,将任务提交给线程池,线程 ...