zoukankan      html  css  js  c++  java
  • 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服务的情况,需要更换用户名与密码时,只需要将密码文件替换一次即可,比第一种方式方便可靠了很多。

  • 相关阅读:
    LeetCode 264. Ugly Number II
    LeetCode 231. Power of Two
    LeetCode 263. Ugly Number
    LeetCode 136. Single Number
    LeetCode 69. Sqrt(x)
    LeetCode 66. Plus One
    LeetCode 70. Climbing Stairs
    LeetCode 628. Maximum Product of Three Numbers
    Leetcode 13. Roman to Integer
    大二暑假周进度报告03
  • 原文地址:https://www.cnblogs.com/lechie/p/2393531.html
Copyright © 2011-2022 走看看