HTTP的 Basic 验证

什么是HTTP Basic Authentication?
在wiki上有详细的解释: http://en.wikipedia.org/wiki/Basic_authentication_scheme
HTTP Basic Authentication是一个定义在HTTP/1.1规范中的验证机制。这种机制是以用户名和密码为基础的。一个web server要求一个web client去验证一个用户。作为request的一部分,web server 传递被称之为realm的字符串,用户就是在它里面被验证的。注意:Basic Authentication机制的realm字符串不一定反映任何一种安全方针域。Web client得到这些用户名和密码,然后把它传递给web server。Web server然后在一个特定的领域验证这些用户。
由于密码是使用一种64位的编码来传递,而且目的server没有验证,所以Basic Authentication不是一种安全的验证协议。
在访问一个需要 HTTP Basic Authentication 的URL的时候,如果你没有提供用户名和密码,服务器就会返回401,
如果你直接在浏览器中打开,浏览器会提示你输入用户名和密码。
你可以尝试点击这个url看看效果:http://api.minicloud.com.cn/statuses/friends_timeline.xml  
如果想要在发送请求的时候添加 HTTP Basic Authentication 认证信息到请求中,有两种方法:  
一是在请求头中添加Authorization:
Authorization: "Basic 用户名和密码的base64加密字符串"  
二是在url中添加用户名和密码:  
http://userName:password@api.minicloud.com.cn/statuses/friends_timeline.xml  
  
//需要Base64见:http://www.webtoolkit.info/javascript-base64.html  
function make_base_auth(user, password) {  
  var tok = user + ':' + pass;  
  var hash = Base64.encode(tok);  
  return "Basic " + hash;  
}   
  
var auth = make_basic_auth('QLeelulu','mypassword');  
var url = 'http://example.com';   
  
// 原始JavaScript  
xml = new XMLHttpRequest();  
xml.setRequestHeader('Authorization', auth);  
xml.open('GET',url)   
  
// ExtJS  
Ext.Ajax.request({  
    url : url,  
    method : 'GET',  
    headers : { Authorization : auth }  
});   
  
// jQuery  
$.ajax({  
    url : url,  
    method : 'GET',  
    beforeSend : function(req) {  
        req.setRequestHeader('Authorization', auth);  
    }  
}); 
HTTP基本认证(HTTP Basic Athorization)过程分析
在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份证的方法,当一个客户端向HTTP服务 器进行数据请求时,如果客户端未被认证,则HTTP服务器将通过基本认证过程对客户端的用户名及密码进行验证,以决定用户是否合法。
客户端在接收到HTTP服务器的身份认证要求后,会提示用户输入用户名及密码,然后将用户名及密码以BASE64加密,加密后的密文将附加于请求信息中, 如当用户名为anjuta,密码为:123456时,客户端将用户名和密码用“:”合并,并将合并后的字符串用BASE64加密为密文,并于每次请求数据 时,将密文附加于请求头(Request Header)中。
   HTTP服务器在每次收到请求包后,根据协议取得客户端附加的用户信息(BASE64加密的用户名和密码),解开请求包,对用户名及密码进行验证,如果用 户名及密码正确,则根据客户端请求,返回客户端所需要的数据;否则,返回错误代码或重新要求客户端提供用户名及密码。
整个交互过程如下(模拟个登录GOOGLE首页的过程,并假设登录GOOGLE需要认证):
1,客户端向服务器请求数据,请求的内容可能是一个网页或者是一个其它的MIME类型,此时,假设客户端尚未被验证,则客户端提供如下请求至服务器:
Get /index.html HTTP/1.0
Host:www.google.com
这段信息表明,客户端向主机www.google.com请求其位于根目录下的index.html网页,使用http1.0协议。
2,服务器向客户端发送验证请求代码401,服务器返回的数据大抵如下:
HTTP/1.0 401 Unauthorised
Server: SokEvo/1.0
WWW-Authenticate: Basic realm="google.com"
Content-Type: text/html
Content-Length: xxx
<HTML>
<HEAD>
    <TITLE>Error</TITLE>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
</HEAD>
<BODY><H1>401 Unauthorised.</H1></BODY>
</HTML>
3,当符合http1.0或1.1规范的客户端(如IE,FIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。
4,用户输入用户名和密码后,将用户名及密码以BASE64加密方式加密,并将密文放入前一条请求信息中,则客户端发送的第一条请求信息则变成如下内容:
Get /index.html HTTP/1.0
Host:www.google.com
Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx
注:xxxx....表示加密后的用户名及密码。
5,服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证,如用户名及密码正确,服务器则根据请求,将所请求资源发送给客户端:
HTTP/1.0 200 OK
Server: www.google.com/http1.0
Content-Type: text/html
Content-Length: xxxx
<html>
网页内容
</html>
如用户名及密码不正确,请返回第2步,重新向客户端发送用户验证请求。
6,在以后的整个通信会话中,客户端均会在请求包中附加入加密后的用户信息。
   HTTP基本认证的目标是提供简单的用户验证功能,其认证过程简单明了,适合于对安全性要求不高的系统或设备中,如大家所用路由器的配置页面的认证,几乎 都采取了这种方式。其缺点是没有灵活可靠的认证策略,如无法提供域(domain或realm)认证功能,另外,BASE64的加密强度非常低,可以说仅 能防止sohu的搜索把它搜到了。当然,HTTP基本认证系统也可以与SSL或者Kerberos结合,实现安全性能较高(相对)的认证系统。
想起用basic验证的服务器端的设置:
方式一:在web.xml中配置,可以参考CATALINA_HOME/server/manager/WEB-INF/web.xml
方式二:在程序中coding,参考如下:
if(request.getHeader("Authorization")==null){ 
    response.setStatus(401); 
    response.setHeader("WWW-authenticate","Basic realm=\"请输入管理员密码\""); 
}else if( !(request.getHeader("Authorization").equals(pass))){
    response.setStatus(401);     
    response.setHeader("WWW-authenticate","Basic realm=\"用户名或者密码错误\"");
    out.print("对不起你没有权限!!");
    return;
}
GET /manager HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64encode(user:pass)>
方法一:直接使用new sun.misc.BASE64Encoder().encode(byte[])构造HTTP头
方法二:  Authenticator.setDefault(new AuthImpl()); 然后使用HttpURLConnection连接即可,这种方式更灵活
class AuthImpl extends Authenticator {
 protected PasswordAuthentication getPasswordAuthentication() {
  String user = "admin";
  char pass[] = "admin".toCharArray();
nginx配置
虽然resin的配置也可以达到效果,但是毕竟是配置到了工程文件中,以后定期更换用户名与密码,都得更新项目描述符;而且有个更要命的问题,如果一个resin上有多个项目的话,一次更新就需要修改所有相关项目的web.xml文件,太麻烦了。在nginx上也可以配置basic认证,而且更简单。
nginx的http basic认证密码是用crypt(3)加密的,可以试用apache的htpasswd生成密码文件。首先进入apache的安装目录,进入apache/bin/目录下,可以看到htpasswd,输入如下命令生成密码文件。
htpasswd -c -d pass_file user_name
其中-c表示生成文件,-d表示是以crypt加密,pass_file是密码文件名,user_name表示basic认证的用户名,回车后会提示输入密码,然后再次输入确认,生成密码文件完成。
然后就是配置nginx,nginx的认证需要配置到location下,如下所示。
location ~ /admin/manage {
    auth_basic  "Auth";
    auth_basic_user_file  pass_file;
}
其中Auth可以随意设置,它只不过是当需要认证时弹出窗口的服务显示名称而已,pass_file就是我们之前生成的密码文件,这里要注意nginx 0.6.7开始,auth_basic_user_file的相对目录是nginx_home/conf,以前版本的相对目录是nginx_home,现在只要访问包含/admin/manage路径的资源都会弹出认证框,而且对于一个nginx代理了n个web服务的情况,需要更换用户名与密码时,只需要将密码文件替换一次即可,比第一种方式方便可靠了很多。

转载于:https://www.cnblogs.com/lechie/archive/2012/03/13/2393531.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值