<?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. javascript基础03

    javascript基础03 1. 算术运算符 后增量/后减量运算符 ++ ,-- 比较运算符 ( >, <, >=, <=, ==, !=,===,!== ) 逻辑运算符( ...

  2. Python自动化之django的ORM

    django ORM操作 1.什么是ORM? ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作 ...

  3. js跨域解决方案(转载)

    1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本 ...

  4. AngularJS ui-router (嵌套路由)

    http://www.oschina.net/translate/angularjs-ui-router-nested-routes AngularJS ui-router (嵌套路由) 英文原文:A ...

  5. python的一道面试题 __call__ 的使用.

    class Person: def __init__(self): self.age = 1 def __call__(self, *args, **kwargs): print 'age', sel ...

  6. cf596d

    题意:有一排等高的树木,高度都为h.给出每棵树在数轴上的坐标,每次有可能是最左边或者最右边的立着的树倒下,概率都是0.5.最终所有树都倒下.每棵树在倒下的时候有p的概率向左倒,1-p的概率向右倒.如果 ...

  7. OC编程之道-创建对象之单例模式

    一 何为单例singleton模式?(what) 保证一个类只有一个实例,并提供一个访问它的全局访问点. 二 何时使用单例模式?(where) 1类只能有一个实例,而且必须从一个为人熟知的访问点对其访 ...

  8. iOS App更改显示的项目名

    添加Key: Bundle display name 后面value直接添加想改变的值

  9. 【linux】su、sudo、sudo su、sudo -i的用法和区别

    来源:http://bbs.csdn.net/topics/390938651 sudo : 暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.不过 ...

  10. xml Schema 基础

    Schema比DTD好在哪儿? 后者简单易用,前者功能更强大也更复杂.DTD可以定义XML文档的结构,但无法对XML元素的内容进行约束,例如,如果希望某个XML元素的内容只能是日期型的数据,DTD就无 ...