在jsp中作HTTP认证的方法
发表于:2007-07-01来源:作者:点击数:
标签:
最近研究了jsp中作HTTP认证的问题,它的工作方式如下:br br 1、server发送一个要求认证代码401和一个头信息WWW-authenticate,激发browser弹出一个认证窗口br br 2、server取得browser送来的认证头quot;Authorizationquot;,它是加密的了,要用Base64方法解密
最近研究了jsp中作HTTP认证的问题,它的工作方式如下:<br>
<br>
1、server发送一个要求认证代码401和一个头信息WWW-authenticate,激发browser弹出一个认证窗口<br>
<br>
2、server取得browser送来的认证头"Authorization",它是加密的了,要用Base64方法解密,取得明文的用户名和密码<br>
<br>
3、检查用户名和密码,根据结果传送不同的页面<br>
<br>
<br>
以下是jsp的片断,你也可以把它做成include文件。和Base64的加解密的class源码。<br>
如有兴趣可与我联系:
unixboy@yeah
.net<br>
<br>
<jsp:useBean id="base64" scope="page" class="Base64"/><br>
<%<br>
if(request.getHeader("Authorization")==null){<br>
response.setStatus(401);<br>
response.setHeader("WWW-authenticate", "Basic re
alm=\"unixboy.com\"");<br>
}else{<br>
String encoded=(request.getHeader("Authorization"));<br>
String tmp=encoded.substring(6);<br>
String up=Base64.decode(tmp);<br>
String user="";<br>
String password="";<br>
if(up!=null){<br>
user=up.substring(0,up.indexOf(":"));<br>
password=up.substring(up.indexOf(":")+1);<br>
}<br>
if(user.equals("unixboy")&&password.equals("123456")){<br>
//认证成功<br>
}else{<br>
//认证失败<br>
}<br>
}<br>
%><br>
<br>
<br>
//消息加解密class<br>
public class Base64<br>
{<br>
/** decode a Base 64 encoded String.<br>
* <p><h4>String to byte conversion</h4><br>
* This method uses a naive String to byte interpretation, it simply gets each<br>
* char of the String and calls it a byte.</p><br>
* <p>Since we should be dealing with Base64 encoded Strings that is a reasonable<br>
* assumption.</p><br>
* <p><h4>End of data</h4><br>
* We don@#t try to stop the converion when we find the "=" end of data padding char.<br>
* We simply add zero bytes to the unencode buffer.</p><br>
*/<br>
public static String decode(String encoded)<br>
{<br>
StringBuffer sb=new StringBuffer();<br>
int maxturns;<br>
//work out how long to loop for.<br>
if(encoded.length()%3==0)<br>
maxturns=encoded.length();<br>
else<br>
maxturns=encoded.length()+(3-(encoded.length()%3));<br>
//tells us whether to include the char in the unencode<br>
boolean skip;<br>
//the unencode buffer<br>
byte[] unenc=new byte[4];<br>
byte b;<br>
for(int i=0,j=0; i<maxturns; i++)<br>
{<br>
skip=false;<br>
//get the byte to convert or 0<br>
if(i<encoded.length())<br>
b=(byte)encoded.charAt(i);<br>
else<br>
b=0;<br>
//test and convert first capital letters, lowercase, digits then @#+@# and @#/@#<br>
if(b>=65 && b<91)<br>
unenc[j]=(byte)(b-65);<br>
else if(b>=97 && b<123)<br>
unenc[j]=(byte)(b-71);<br>
else if(b>=48 && b<58)<br>
unenc[j]=(byte)(b+4);<br>
else if(b==@#+@#)<br>
unenc[j]=62;<br>
else if(b==@#/@#)<br>
unenc[j]=63;<br>
//if we find "=" then data has finished, we@#re not really dealing with this now<br>
else if(b==@#=@#)<br>
unenc[j]=0;<br>
else<br>
{<br>
char c=(char)b;<br>
if(c==@#\n@# || c==@#\r@# || c==@# @# || c==@#\t@#)<br>
skip=true;<br>
else<br>
//could throw an exception here? it@#s input we don@#t understand.<br>
;<br>
}<br>
//once the array has boiled convert the bytes back into chars<br>
if(!skip && ++j==4)<br>
{<br>
//shift the 6 bit bytes into a single 4 octet word<br>
int res=(unenc[0] << 18)+(unenc[1] << 12)+(unenc[2] << 6)+unenc[3];<br>
byte c;<br>
int k=16;<br>
//shift each octet down to read it as char and add to StringBuffer<br>
while(k>=0)<br>
{<br>
c=(byte)(res >> k);<br>
if ( c > 0 )<br>
sb.append((char)c);<br>
k-=8;<br>
}<br>
//reset j and the unencode buffer<br>
j=0;<br>
unenc[0]=0;unenc[1]=0;unenc[2]=0;unenc[3]=0;<br>
}<br>
}<br>
return sb.toString();<br>
}<br>
<br>
/** encode plaintext data to a base 64 string<br>
* @param plain the text to convert. If plain is longer than 76 characters this method<br>
* returns null (see RFC2045).<br>
* @return the encoded text (or null if string was longer than 76 chars).<br>
*/<br>
public static String encode(String plain)<br>
{<br>
if(plain.length()>76)<br>
return null;<br>
int maxturns;<br>
StringBuffer sb=new StringBuffer();<br>
//the encode buffer<br>
byte[] enc=new byte[3];<br>
boolean end=false;<br>
for(int i=0,j=0; !end; i++)<br>
{<br>
char _ch=plain.charAt(i);<br>
if(i==plain.length()-1)<br>
end=true;<br>
enc[j++]=(byte)plain.charAt(i);<br>
if(j==3 || end)<br>
{<br>
int res;<br>
//this is a bit inefficient at the end point<br>
//worth it for the small decrease in code size?<br>
res=(enc[0] << 16)+(enc[1] << 8)+enc[2];<br>
int b;<br>
int lowestbit=18-(j*6);<br>
for(int toshift=18; toshift>=lowestbit; toshift-=6)<br>
{<br>
b=res >>> toshift;<br>
b&=63;<br>
if(b>=0 && b<26)<br>
sb.append((char)(b+65));<br>
if(b>=26 && b<52)<br>
sb.append((char)(b+71));<br>
if(b>=52 && b<62)<br>
sb.append((char)(b-4));<br>
if(b==62)<br>
sb.append(@#+@#);<br>
if(b==63)<br>
sb.append(@#/@#);<br>
if(sb.length()%76==0)<br>
sb.append(@#\n@#);<br>
}<br>
//now set the end chars to be pad character if there <br>
//was less than integral input (ie: less than 24 bits)<br>
if(end)<br>
{<br>
if(j==1)<br>
sb.append("==");<br>
if(j==2)<br>
sb.append(@#=@#);<br>
}<br>
enc[0]=0; enc[1]=0; enc[2]=0;<br>
j=0;<br>
}<br>
}<br>
return sb.toString();<br>
}<br>
}<br>
原文转自:http://www.ltesting.net