前言
HTTP认证是Web服务器对客户端的权限进行认证的一种方式,能够为Web应用(如jsp)提供一定程度的安全保障。目前一些Web应用项目(如jsp)已经提出了采用HTTP认证的需求。虽然一般的Web容器都提供基本认证和摘要认证的API,但不同的Web容器提供的API也互不相同,因此我们在ZX Web平台的工具包中提供了一组API,利用这组API,开发人员可以在应用程序中使用统一的接口轻松实现HTTP认证功能,而不必依赖于Web容器。
最近研究了jsp中作HTTP认证的问题,它的工作方式如下:
1、server发送一个要求认证代码401和一个头信息WWW-authenticate,激发browser弹出一个认证窗口
2、server取得browser送来的认证头"Authorization",它是加密的了,要用Base64方法解密,取得明文的用户名和密码
3、检查用户名和密码,根据结果传送不同的页面
以下是jsp的片断,你也可以把它做成include文件。和Base64的加解密的class源码。如有兴趣可与他联系:unixboy@yeah.net
- <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{
- //认证失败
- }
- }
- %>
- //消息加解密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();
- }
- }
本文转自网络,程序如有错误请与原作者联系,本程序leo未加验证。leo整理了一些资料,希望能对研究下方面知识的朋友有用处
相关文章: