在JSP中实现HTTP认证安全

前言

 

        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

XML/HTML代码
  1. <jsp:useBean id="base64" scope="page" class="Base64"/>  
  2. <%   
  3. if(request.getHeader("Authorization")==null){   
  4. response.setStatus(401);   
  5. response.setHeader("WWW-authenticate", "Basic realm="unixboy.com"");   
  6. }else{   
  7. String encoded=(request.getHeader("Authorization"));   
  8. String tmp=encoded.substring(6);   
  9. String up=Base64.decode(tmp);   
  10. String user="";   
  11. String password="";   
  12. if(up!=null){   
  13. user=up.substring(0,up.indexOf(":"));   
  14. password=up.substring(up.indexOf(":")+1);   
  15. }   
  16. if(user.equals("unixboy")&&password.equals("123456")){   
  17. //认证成功   
  18. }else{   
  19. //认证失败   
  20. }   
  21. }   
  22. %>  
  23.   
  24.   
  25. //消息加解密class   
  26. public class Base64   
  27. {   
  28. /** decode a Base 64 encoded String.   
  29. <p><h4>String to byte conversion</h4>  
  30. * This method uses a naive String to byte interpretation, it simply gets each   
  31. * char of the String and calls it a byte.</p>  
  32. <p>Since we should be dealing with Base64 encoded Strings that is a reasonable   
  33. * assumption.</p>  
  34. <p><h4>End of data</h4>  
  35. * We don´t try to stop the converion when we find the "=" end of data padding char.   
  36. * We simply add zero bytes to the unencode buffer.</p>  
  37. */   
  38. public static String decode(String encoded)   
  39. {   
  40. StringBuffer sb=new StringBuffer();   
  41. int maxturns;   
  42. //work out how long to loop for.   
  43. if(encoded.length()%3==0)   
  44. maxturns=encoded.length();   
  45. else   
  46. maxturns=encoded.length()+(3-(encoded.length()%3));   
  47. //tells us whether to include the char in the unencode   
  48. boolean skip;   
  49. //the unencode buffer   
  50. byte[] unenc=new byte[4];   
  51. byte b;   
  52. for(int i=0,j=0; i<maxturns; i++)   
  53. {   
  54. skip=false;   
  55. //get the byte to convert or 0   
  56. if(i<encoded.length())   
  57. b=(byte)encoded.charAt(i);   
  58. else   
  59. b=0;   
  60. //test and convert first capital letters, lowercase, digits then ´+´ and ´/´   
  61. if(b>=65 && b<91)   
  62. unenc[j]=(byte)(b-65);   
  63. else if(b>=97 && b<123)   
  64. unenc[j]=(byte)(b-71);   
  65. else if(b>=48 && b<58)   
  66. unenc[j]=(byte)(b+4);   
  67. else if(b==´+´)   
  68. unenc[j]=62;   
  69. else if(b==´/´)   
  70. unenc[j]=63;   
  71. //if we find "=" then data has finished, we´re not really dealing with this now   
  72. else if(b==´=´)   
  73. unenc[j]=0;   
  74. else   
  75. {   
  76. char c=(char)b;   
  77. if(c==´ ´ || c==´ ´ || c==´ ´ || c==´ ´)   
  78. skip=true;   
  79. else   
  80. //could throw an exception here? it´s input we don´t understand.   
  81. ;   
  82. }   
  83. //once the array has boiled convert the bytes back into chars   
  84. if(!skip && ++j==4)   
  85. {   
  86. //shift the 6 bit bytes into a single 4 octet word   
  87. int res=(unenc[0] << 18)+(unenc[1] << 12)+(unenc[2] << 6)+unenc[3];   
  88. byte c;   
  89. int k=16;   
  90. //shift each octet down to read it as char and add to StringBuffer   
  91. while(k>=0)   
  92. {   
  93. c=(byte)(res >> k);   
  94. if ( c > 0 )   
  95. sb.append((char)c);   
  96. k-=8;   
  97. }   
  98. //reset j and the unencode buffer   
  99. j=0;   
  100. unenc[0]=0;unenc[1]=0;unenc[2]=0;unenc[3]=0;   
  101. }   
  102. }   
  103. return sb.toString();   
  104. }   
  105.   
  106. /** encode plaintext data to a base 64 string   
  107. * @param plain the text to convert. If plain is longer than 76 characters this method   
  108. * returns null (see RFC2045).   
  109. * @return the encoded text (or null if string was longer than 76 chars).   
  110. */   
  111. public static String encode(String plain)   
  112. {   
  113. if(plain.length()>76)   
  114. return null;   
  115. int maxturns;   
  116. StringBuffer sb=new StringBuffer();   
  117. //the encode buffer   
  118. byte[] enc=new byte[3];   
  119. boolean end=false;   
  120. for(int i=0,j=0; !end; i++)   
  121. {   
  122. char _ch=plain.charAt(i);   
  123. if(i==plain.length()-1)   
  124. end=true;   
  125. enc[j++]=(byte)plain.charAt(i);   
  126. if(j==3 || end)   
  127. {   
  128. int res;   
  129. //this is a bit inefficient at the end point   
  130. //worth it for the small decrease in code size?   
  131. res=(enc[0] << 16)+(enc[1] << 8)+enc[2];   
  132. int b;   
  133. int lowestbit=18-(j*6);   
  134. for(int toshift=18; toshift>=lowestbit; toshift-=6)   
  135. {   
  136. b=res >>> toshift;   
  137. b&=63;   
  138. if(b>=0 && b<26)   
  139. sb.append((char)(b+65));   
  140. if(b>=26 && b<52)   
  141. sb.append((char)(b+71));   
  142. if(b>=52 && b<62)   
  143. sb.append((char)(b-4));   
  144. if(b==62)   
  145. sb.append(´+´);   
  146. if(b==63)   
  147. sb.append(´/´);   
  148. if(sb.length()%76==0)   
  149. sb.append(´ ´);   
  150. }   
  151. //now set the end chars to be pad character if there    
  152. //was less than integral input (ie: less than 24 bits)   
  153. if(end)   
  154. {   
  155. if(j==1)   
  156. sb.append("==");   
  157. if(j==2)   
  158. sb.append(´=´);   
  159. }   
  160. enc[0]=0; enc[1]=0; enc[2]=0;   
  161. j=0;   
  162. }   
  163. }   
  164. return sb.toString();   
  165. }   
  166. }   

        本文转自网络,程序如有错误请与原作者联系,本程序leo未加验证。leo整理了一些资料,希望能对研究下方面知识的朋友有用处

 

相关文章:

转载于:https://my.oschina.net/dukai168/blog/6908

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值