问题:
最近做项目Http请求需要要用到 (HTTP Basic Authentication认证),这里整理了一下以供大家参考
- 什么是HTTP Basic Authentication?直接看http://en.wikipedia.org/wiki/Basic_authentication_scheme吧。
- 在你访问一个需要HTTP Basic Authentication的URL的时候,如果你没有提供用户名和密码,服务器就会返回401,如果你直接在浏览器中打开,浏览器会提示你输入用户名和密码(google浏览器不会,bug?)。你可以尝试点击这个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);
- }
- });
- <span style="font-family: Verdana, sans-serif; color: #444444;"><span>下面摘录一段 Jsp实现鉴权的代码逻辑</span></span>
- <pre class=" 以下是一段Jsp鉴权操作 " name="code"> 以下是一段Jsp鉴权操作
- 1、server发送一个要求认证代码401和一个头信息WWW-authenticate,激发browser弹出一个认证窗口
- 2、server取得browser送来的认证头"Authorization",它是加密的了,要用Base64方法解密,取得明文的用户名和密码
- 3、检查用户名和密码,根据结果传送不同的页面</pre>
- =========Jsp代码===================
- <jsp:useBean id="base64" scope="page" class="Base64"/>
- <%
- if(request.getHeader("Authorization")==null){
- response.setStatus(401);
- response.setHeader("WWW-authenticate", "Basic realm="unixboy.com"");
- }else{
- String encoded=(request.getHeader("Authorization"));
- String tmp=encoded.substring(6);
- String up=Base64.decode(tmp);
- String user="";
- String password="";
- if(up!=null){
- user=up.substring(0,up.indexOf(":"));
- password=up.substring(up.indexOf(":")+1);
- }
- if(user.equals("unixboy")&&password.equals("123456")){
- //认证成功
- }else{
- //认证失败
- }
- }
- %>
- =======Java段代码==================
- //消息加解密class
- public class Base64
- {
- /** decode a Base 64 encoded String.
- * <p><h4>String to byte conversion</h4>
- * This method uses a naive String to byte interpretation, it simply gets each
- * char of the String and calls it a byte.</p>
- * <p>Since we should be dealing with Base64 encoded Strings that is a reasonable
- * assumption.</p>
- * <p><h4>End of data</h4>
- * We don′t try to stop the converion when we find the "=" end of data padding char.
- * We simply add zero bytes to the unencode buffer.</p>
- */
- public static String decode(String encoded)
- {
- StringBuffer sb=new StringBuffer();
- int maxturns;
- //work out how long to loop for.
- if(encoded.length()%3==0)
- maxturns=encoded.length();
- else
- maxturns=encoded.length()+(3-(encoded.length()%3));
- //tells us whether to include the char in the unencode
- boolean skip;
- //the unencode buffer
- byte[] unenc=new byte[4];
- byte b;
- for(int i=0,j=0; i<maxturns; i++)
- {
- skip=false;
- //get the byte to convert or 0
- if(i<encoded.length())
- b=(byte)encoded.charAt(i);
- else
- b=0;
- //test and convert first capital letters, lowercase, digits then ′+′ and ′/′
- if(b>=65 && b<91)
- unenc[j]=(byte)(b-65);
- else if(b>=97 && b<123)
- unenc[j]=(byte)(b-71);
- else if(b>=48 && b<58)
- unenc[j]=(byte)(b+4);
- else if(b==′+′)
- unenc[j]=62;
- else if(b==′/′)
- unenc[j]=63;
- //if we find "=" then data has finished, we′re not really dealing with this now
- else if(b==′=′)
- unenc[j]=0;
- else
- {
- char c=(char)b;
- if(c==′ ′ || c==′ ′ || c==′ ′ || c==′ ′)
- skip=true;
- else
- //could throw an exception here? it′s input we don′t understand.
- ;
- }
- //once the array has boiled convert the bytes back into chars
- if(!skip && ++j==4)
- {
- //shift the 6 bit bytes into a single 4 octet word
- int res=(unenc[0] << 18)+(unenc[1] << 12)+(unenc[2] << 6)+unenc[3];
- byte c;
- int k=16;
- //shift each octet down to read it as char and add to StringBuffer
- while(k>=0)
- {
- c=(byte)(res >> k);
- if ( c > 0 )
- sb.append((char)c);
- k-=8;
- }
- //reset j and the unencode buffer
- j=0;
- unenc[0]=0;unenc[1]=0;unenc[2]=0;unenc[3]=0;
- }
- }
- return sb.toString();
- }
- /** encode plaintext data to a base 64 string
- * @param plain the text to convert. If plain is longer than 76 characters this method
- * returns null (see RFC2045).
- * @return the encoded text (or null if string was longer than 76 chars).
- */
- public static String encode(String plain)
- {
- if(plain.length()>76)
- return null;
- int maxturns;
- StringBuffer sb=new StringBuffer();
- //the encode buffer
- byte[] enc=new byte[3];
- boolean end=false;
- for(int i=0,j=0; !end; i++)
- {
- char _ch=plain.charAt(i);
- if(i==plain.length()-1)
- end=true;
- enc[j++]=(byte)plain.charAt(i);
- if(j==3 || end)
- {
- int res;
- //this is a bit inefficient at the end point
- //worth it for the small decrease in code size?
- res=(enc[0] << 16)+(enc[1] << 8)+enc[2];
- int b;
- int lowestbit=18-(j*6);
- for(int toshift=18; toshift>=lowestbit; toshift-=6)
- {
- b=res >>> toshift;
- b&=63;
- if(b>=0 && b<26)
- sb.append((char)(b+65));
- if(b>=26 && b<52)
- sb.append((char)(b+71));
- if(b>=52 && b<62)
- sb.append((char)(b-4));
- if(b==62)
- sb.append(′+′);
- if(b==63)
- sb.append(′/′);
- if(sb.length()%76==0)
- sb.append(′ ′);
- }
- //now set the end chars to be pad character if there
- //was less than integral input (ie: less than 24 bits)
- if(end)
- {
- if(j==1)
- sb.append("==");
- if(j==2)
- sb.append(′=′);
- }
- enc[0]=0; enc[1]=0; enc[2]=0;
- j=0;
- }
- }
- return sb.toString();
- }
- }
给个直观截图示例吧:(不懂得可以留言下方)
注意:
这里的map 是我自己封装 工具类中自定义添加请求头用的, 参考即可
public static byte[] doGet(String url, Map<String, String> headerMap, String proxyUrl, int proxyPort) {
byte[] content = null;
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(url);
// getMethod.addRequestHeader("Content-Type", "text/html; charset=UTF-8");
if (headerMap != null) {
// 头部请求信息
if (headerMap != null) {
Iterator iterator = headerMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry entry = (Entry) iterator.next();
getMethod.addRequestHeader(entry.getKey().toString(), entry.getValue().toString());
}
}
}
if (StringUtils.isNotBlank(proxyUrl)) {
httpClient.getHostConfiguration().setProxy(proxyUrl, proxyPort);
}
// 设置成了默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 10000);
// postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER , new
// DefaultHttpMethodRetryHandler());
InputStream inputStream = null;
try {
if (httpClient.executeMethod(getMethod) == HttpStatus.SC_OK) {
// 读取内容
inputStream = getMethod.getResponseBodyAsStream();
content = IOUtils.toByteArray(inputStream);
} else {
System.err.println("Method failed: " + getMethod.getStatusLine());
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
getMethod.releaseConnection();
}
return content;
}