PHP 模拟 HTTP 摘要认证(Digest )
<?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'];
}
<PHP Cookbook,3rd>
PHP 模拟 HTTP 摘要认证(Digest )的更多相关文章
- [转]ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)
本文转自:http://www.cnblogs.com/parry/p/ASPNET_MVC_Web_API_digest_authentication.html 在前一篇文章中,主要讨论了使用HTT ...
- ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)
在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看另一种验证的方式:digest authentication,即摘要认 ...
- 安全验证之使用摘要认证(digest authentication)
安全验证之使用摘要认证(digest authentication) 在前一篇文章中,主要讨论了使用HTTP基本认证的方法,因为HTTP基本认证的方式决定了它在安全性方面存在很大的问题,所以接下来看看 ...
- asp.net权限认证:摘要认证(digest authentication)
asp.net权限认证系列 asp.net权限认证:Forms认证 asp.net权限认证:HTTP基本认证(http basic) asp.net权限认证:Windows认证 asp.net权限认证 ...
- [转]asp.net权限认证:摘要认证(digest authentication)
本文转自:http://www.cnblogs.com/lanxiaoke/p/6357501.html 摘要认证简单介绍 摘要认证是对基本认证的改进,即是用摘要代替账户密码,从而防止明文传输中账户密 ...
- HTTP认证之摘要认证——Digest(一)
导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 一.概述 Di ...
- HTTP认证之摘要认证——Digest(二)
导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 在HTTP认证 ...
- Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结
Atitit HTTP认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结 1.1. 最广泛使用的是基本验证 ( ...
- ASP.NET Web API 安全验证之摘要(Digest)认证
在基本认证的方式中,主要的安全问题来自于用户信息的明文传输,而在摘要认证中,主要通过一些手段避免了此问题,大大增加了安全性. 1.客户端匿名的方式请求 (无认证) HTTP/ Unauthorized ...
随机推荐
- javascript基础01
javascript基础01 Javascript能做些什么? 给予页面灵魂,让页面可以动起来,包括动态的数据,动态的标签,动态的样式等等. 如实现到轮播图.拖拽.放大镜等,而动态的数据就好比不像没有 ...
- C#高级编程笔记 Day 4, 2016年9月 12日(接口)
1.定义和实现接口:接口名称通常上以字母 I 开头 例子:定义IBankAccount接口 namespace Test.YinXi{ public interface IBankAccount{ v ...
- word20161215
name / 名称 name mapping / 名称映射 name resolution / 名称解析 name server (NS) resource record / 名称服务器资源记录 na ...
- Java 网络编程之 Socket
========================UDP============================= UDP---用户数据报协议,是一个简单的面向数据报的运输层协议. UDP不提供可靠性, ...
- 配置ngnix
server { listen ; server_name www.aaa.com; root /home/www/...; index index.php index.html index.htm; ...
- Servlet 之 HttpServlet
package cn.jiemoxiaodi.http; import java.io.IOException; import javax.servlet.GenericServlet; import ...
- JavaScript高级程序设计学习笔记--事件
HTML事件处理程序 <input type="button" value="Click Me" onclick"showMessage()&q ...
- 1.UI初认识
前节:app是什么? app英文全称:application 应用程序,简称应用.也就是手机应用的简写 出处:http://www.cnblogs.com/mcj-coding/p/5098254.h ...
- NavigationController
前面的一篇文章<iOS开发16:使用Navigation Controller切换视图>中的小例子在运行时,屏幕上方出现的工具栏就是Navigation Bar,而所谓UINavigati ...
- PHP基础之POST与GET
post 与 get区别 *.Post传输数据时,不需要在URL中显示出来,而Get方法要在URL中显示.*.Post传输的数据量大,可以达到2M,而Get方法由于受到URL长度的限制,只能传递大约1 ...