Advertisement
Guest User

Untitled

a guest
Oct 19th, 2018
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.87 KB | None | 0 0
  1. /*
  2. * To change this template, choose Tools | Templates
  3. * and open the template in the editor.
  4. */
  5. package com.example.http.authenticate;
  6.  
  7. import java.io.*;
  8. import java.text.SimpleDateFormat;
  9. import java.util.Date;
  10. import java.util.HashMap;
  11. import java.util.Random;
  12. import java.util.concurrent.Executors;
  13. import java.util.concurrent.ScheduledExecutorService;
  14. import java.util.concurrent.TimeUnit;
  15. import javax.servlet.ServletException;
  16. import javax.servlet.http.HttpServlet;
  17. import javax.servlet.http.HttpServletRequest;
  18. import javax.servlet.http.HttpServletResponse;
  19. import org.apache.commons.codec.digest.DigestUtils;
  20. import org.apache.commons.lang3.StringUtils;
  21.  
  22. /**
  23. * TODO stale support
  24. * TODO give this servlet and package a correct name
  25. * @author Usama Dar( munir.usama@gmail.com)
  26. */
  27. public class HttpDigestAuthServlet extends HttpServlet {
  28.  
  29. private String authMethod = "auth";
  30. private String userName = "usm";
  31. private String password = "password";
  32. private String realm = "example.com";
  33.  
  34. public String nonce;
  35. public ScheduledExecutorService nonceRefreshExecutor;
  36.  
  37. /**
  38. * Default constructor to initialize stuff
  39. *
  40. */
  41. public HttpDigestAuthServlet() throws IOException, Exception {
  42.  
  43. nonce = calculateNonce();
  44.  
  45. nonceRefreshExecutor = Executors.newScheduledThreadPool(1);
  46.  
  47. nonceRefreshExecutor.scheduleAtFixedRate(new Runnable() {
  48.  
  49. public void run() {
  50. log("Refreshing Nonce....");
  51. nonce = calculateNonce();
  52. }
  53. }, 1, 1, TimeUnit.MINUTES);
  54.  
  55. }
  56.  
  57. protected void authenticate(HttpServletRequest request, HttpServletResponse response)
  58. throws ServletException, IOException {
  59.  
  60. response.setContentType("text/html;charset=UTF-8");
  61. PrintWriter out = response.getWriter();
  62.  
  63. String requestBody = readRequestBody(request);
  64.  
  65. try {
  66. String authHeader = request.getHeader("Authorization");
  67. if (StringUtils.isBlank(authHeader)) {
  68. response.addHeader("WWW-Authenticate", getAuthenticateHeader());
  69. response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  70. } else {
  71. if (authHeader.startsWith("Digest")) {
  72. // parse the values of the Authentication header into a hashmap
  73. HashMap<String, String> headerValues = parseHeader(authHeader);
  74.  
  75. String method = request.getMethod();
  76.  
  77. String ha1 = DigestUtils.md5Hex(userName + ":" + realm + ":" + password);
  78.  
  79. String qop = headerValues.get("qop");
  80.  
  81. String ha2;
  82.  
  83. String reqURI = headerValues.get("uri");
  84.  
  85. if (!StringUtils.isBlank(qop) && qop.equals("auth-int")) {
  86. String entityBodyMd5 = DigestUtils.md5Hex(requestBody);
  87. ha2 = DigestUtils.md5Hex(method + ":" + reqURI + ":" + entityBodyMd5);
  88. } else {
  89. ha2 = DigestUtils.md5Hex(method + ":" + reqURI);
  90. }
  91.  
  92. String serverResponse;
  93.  
  94. if (StringUtils.isBlank(qop)) {
  95. serverResponse = DigestUtils.md5Hex(ha1 + ":" + nonce + ":" + ha2);
  96.  
  97. } else {
  98. String domain = headerValues.get("realm");
  99.  
  100. String nonceCount = headerValues.get("nc");
  101. String clientNonce = headerValues.get("cnonce");
  102.  
  103. serverResponse = DigestUtils.md5Hex(ha1 + ":" + nonce + ":"
  104. + nonceCount + ":" + clientNonce + ":" + qop + ":" + ha2);
  105.  
  106. }
  107. String clientResponse = headerValues.get("response");
  108.  
  109. if (!serverResponse.equals(clientResponse)) {
  110. response.addHeader("WWW-Authenticate", getAuthenticateHeader());
  111. response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
  112. }
  113. } else {
  114. response.sendError(HttpServletResponse.SC_UNAUTHORIZED, " This Servlet only supports Digest Authorization");
  115. }
  116.  
  117. }
  118.  
  119. /*
  120. * out.println("<head>"); out.println("<title>Servlet
  121. * HttpDigestAuth</title>"); out.println("</head>");
  122. * out.println("<body>"); out.println("<h1>Servlet HttpDigestAuth at
  123. * " + request.getContextPath () + "</h1>"); out.println("</body>");
  124. * out.println("</html>");
  125. */
  126. } finally {
  127. out.close();
  128. }
  129. }
  130.  
  131. /**
  132. * Handles the HTTP
  133. * <code>GET</code> method.
  134. *
  135. * @param request servlet request
  136. * @param response servlet response
  137. * @throws ServletException if a servlet-specific error occurs
  138. * @throws IOException if an I/O error occurs
  139. */
  140. @Override
  141. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  142. throws ServletException, IOException {
  143. authenticate(request, response);
  144. }
  145.  
  146. /**
  147. * Handles the HTTP
  148. * <code>POST</code> method.
  149. *
  150. * @param request servlet request
  151. * @param response servlet response
  152. * @throws ServletException if a servlet-specific error occurs
  153. * @throws IOException if an I/O error occurs
  154. */
  155. @Override
  156. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  157. throws ServletException, IOException {
  158. authenticate(request, response);
  159. }
  160.  
  161. /**
  162. * Returns a short description of the servlet.
  163. *
  164. * @return a String containing servlet description
  165. */
  166. @Override
  167. public String getServletInfo() {
  168. return "This Servlet Implements The HTTP Digest Auth as per RFC2617";
  169. }// </editor-fold>
  170.  
  171. /**
  172. * Gets the Authorization header string minus the "AuthType" and returns a
  173. * hashMap of keys and values
  174. *
  175. * @param headerString
  176. * @return
  177. */
  178. private HashMap<String, String> parseHeader(String headerString) {
  179. // seperte out the part of the string which tells you which Auth scheme is it
  180. String headerStringWithoutScheme = headerString.substring(headerString.indexOf(" ") + 1).trim();
  181. HashMap<String, String> values = new HashMap<String, String>();
  182. String keyValueArray[] = headerStringWithoutScheme.split(",");
  183. for (String keyval : keyValueArray) {
  184. if (keyval.contains("=")) {
  185. String key = keyval.substring(0, keyval.indexOf("="));
  186. String value = keyval.substring(keyval.indexOf("=") + 1);
  187. values.put(key.trim(), value.replaceAll("\"", "").trim());
  188. }
  189. }
  190. return values;
  191. }
  192.  
  193. private String getAuthenticateHeader() {
  194. String header = "";
  195.  
  196. header += "Digest realm=\"" + realm + "\",";
  197. if (!StringUtils.isBlank(authMethod)) {
  198. header += "qop=" + authMethod + ",";
  199. }
  200. header += "nonce=\"" + nonce + "\",";
  201. header += "opaque=\"" + getOpaque(realm, nonce) + "\"";
  202.  
  203. return header;
  204. }
  205.  
  206. /**
  207. * Calculate the nonce based on current time-stamp upto the second, and a
  208. * random seed
  209. *
  210. * @return
  211. */
  212. public String calculateNonce() {
  213. Date d = new Date();
  214. SimpleDateFormat f = new SimpleDateFormat("yyyy:MM:dd:hh:mm:ss");
  215. String fmtDate = f.format(d);
  216. Random rand = new Random(100000);
  217. Integer randomInt = rand.nextInt();
  218. return DigestUtils.md5Hex(fmtDate + randomInt.toString());
  219. }
  220.  
  221. private String getOpaque(String domain, String nonce) {
  222. return DigestUtils.md5Hex(domain + nonce);
  223. }
  224.  
  225. /**
  226. * Returns the request body as String
  227. *
  228. * @param request
  229. * @return
  230. * @throws IOException
  231. */
  232. private String readRequestBody(HttpServletRequest request) throws IOException {
  233. StringBuilder stringBuilder = new StringBuilder();
  234. BufferedReader bufferedReader = null;
  235. try {
  236. InputStream inputStream = request.getInputStream();
  237. if (inputStream != null) {
  238. bufferedReader = new BufferedReader(new InputStreamReader(
  239. inputStream));
  240. char[] charBuffer = new char[128];
  241. int bytesRead = -1;
  242. while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
  243. stringBuilder.append(charBuffer, 0, bytesRead);
  244. }
  245. } else {
  246. stringBuilder.append("");
  247. }
  248. } catch (IOException ex) {
  249. throw ex;
  250. } finally {
  251. if (bufferedReader != null) {
  252. try {
  253. bufferedReader.close();
  254. } catch (IOException ex) {
  255. throw ex;
  256. }
  257. }
  258. }
  259. String body = stringBuilder.toString();
  260. return body;
  261. }
  262.  
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement