最近研究了jsp中作HTTP认证的问题,它的工作方式如下:
1、server发送一个要求认证代码401和一个头信息WWW-authenticate,激发browser弹出一个认证窗口
2、server取得browser送来的认证头"Authorization",它是加密的了,要用Base64方法解密,取得明文的用户名和密码
3、检查用户名和密码,根据结果传送不同的页面
以下是jsp的片断,你也可以把它做成include文件。和Base64的加解密的class源码。
如有兴趣可与我联系: [email protected]
1<jsp:usebean class="Base64" id="base64" scope="page"></jsp:usebean>
1
2if(request.getHeader("Authorization")==null){
3response.setStatus(401);
4response.setHeader("WWW-authenticate","Basic realm=\"unixboy.com\"");
5}else{
6String encoded=(request.getHeader("Authorization"));
7String tmp=encoded.substring(6);
8String up=Base64.decode(tmp);
9String user="";
10String password="";
11if(up!=null){
12user=up.substring(0,up.indexOf(":"));
13password=up.substring(up.indexOf(":")+1);
14}
15if(user.equals("unixboy")&&password.equals("123456")){
16//认证成功
17}else{
18//认证失败
19}
20}
//消息加解密class
public class Base64
{
/** decode a Base 64 encoded String.
*
1<p><h4>String to byte conversion</h4>
2* This method uses a naive String to byte interpretation, it simply gets each
3* char of the String and calls it a byte.</p>
1<p>Since we should be dealing with Base64 encoded Strings that is a reasonable
2* assumption.</p>
1<p><h4>End of data</h4>
2* We don''t try to stop the converion when we find the"="end of data padding char.
3* 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
1<maxturns;i++) ''="" ''+''="" 0="" and="" b="0;" byte="" capital="" convert="" digits="" else="" first="" get="" if(b="" if(i<encoded.length())="" letters,="" lowercase,="" or="" skip="false;" test="" the="" then="" to="" {="">=65&&b<91)
2unenc[j]=(byte)(b-65);
3else if(b>=97&&b<123)
4unenc[j]=(byte)(b-71);
5else if(b>=48&&b<58)
6unenc[j]=(byte)(b+4);
7else if(b==''+'')
8unenc[j]=62;
9else if(b==''/'')
10unenc[j]=63;
11//if we find"="then data has finished, we''re not really dealing with this now
12else if(b==''='')
13unenc[j]=0;
14else
15{
16char c=(char)b;
17if(c==''\n'' || c==''\r'' || c=='' '' || c==''\t'')
18skip=true;
19else
20//could throw an exception here? it''s input we don''t understand.
21;
22}
23//once the array has boiled convert the bytes back into chars
24if(!skip&&++j==4)
25{
26//shift the 6 bit bytes into a single 4 octet word
27int res=(unenc[0]<<18)+(unenc[1]<<12)+(unenc[2]<<6)+unenc[3];
28byte c;
29int k=16;
30//shift each octet down to read it as char and add to StringBuffer
31while(k>=0)
32{
33c=(byte)(res>>k);
34if ( c>0 )
35sb.append((char)c);
36k-=8;
37}
38//reset j and the unencode buffer
39j=0;
40unenc[0]=0;unenc[1]=0;unenc[2]=0;unenc[3]=0;
41}
42}
43return sb.toString();
44}
45
46/** encode plaintext data to a base 64 string
47* @param plain the text to convert. If plain is longer than 76 characters this method
48* returns null (see RFC2045).
49* @return the encoded text (or null if string was longer than 76 chars).
50*/
51public static String encode(String plain)
52{
53if(plain.length()>76)
54return null;
55int maxturns;
56StringBuffer sb=new StringBuffer();
57//the encode buffer
58byte[] enc=new byte[3];
59boolean end=false;
60for(int i=0,j=0;!end;i++)
61{
62char _ch=plain.charAt(i);
63if(i==plain.length()-1)
64end=true;
65enc[j++]=(byte)plain.charAt(i);
66if(j==3 || end)
67{
68int res;
69//this is a bit inefficient at the end point
70//worth it for the small decrease in code size?
71res=(enc[0]<<16)+(enc[1]<<8)+enc[2];
72int b;
73int lowestbit=18-(j*6);
74for(int toshift=18;toshift>=lowestbit;toshift-=6)
75{
76b=res>>>toshift;
77b&=63;
78if(b>=0&&b<26)
79sb.append((char)(b+65));
80if(b>=26&&b<52)
81sb.append((char)(b+71));
82if(b>=52&&b<62)
83sb.append((char)(b-4));
84if(b==62)
85sb.append(''+'');
86if(b==63)
87sb.append(''/'');
88if(sb.length()%76==0)
89sb.append(''\n'');
90}
91//now set the end chars to be pad character if there
92//was less than integral input (ie: less than 24 bits)
93if(end)
94{
95if(j==1)
96sb.append("==");
97if(j==2)
98sb.append(''='');
99}
100enc[0]=0;enc[1]=0;enc[2]=0;
101j=0;
102}
103}
104return sb.toString();
105}
106}</maxturns;i++)>