package org.aperteworkflow.gui.auth; import pl.net.bluesoft.rnd.processtool.plugins.PermissionFilter; import pl.net.bluesoft.rnd.processtool.plugins.TokenInfo; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; /** * @author tlipski@bluesoft.net.pl */ public class GenerateTokenServlet extends HttpServlet { //test url: //http://localhost:8080/jbpm-gui-0.1/g_token?returl=http://localhost:8080/jbpm-gui-0.1/g_token?token= private static final String LAST_TOKEN = "__APERTE__LAST_TOKEN"; private static final String TOKEN_MAP = "__APERTE__TOKEN_MAP"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext sc = req.getSession().getServletContext(); HashMap<String, TokenInfo> tokenMap = getTokenMap(sc); cleanupTokens(tokenMap); if (req.getParameter("token") == null && req.getParameter("returl") != null) { String token = Math.random()*(double)System.nanoTime()+req.toString(); try { MessageDigest md = MessageDigest.getInstance("SHA-1"); token = toHex(md.digest(token.getBytes())); req.getSession().setAttribute(LAST_TOKEN, token); resp.sendRedirect(req.getParameter("returl") + token); tokenMap.put(token, new TokenInfo(token, (String)req.getSession().getAttribute(PermissionFilter.AUTHORIZED), new Date(), 1)); } catch (NoSuchAlgorithmException e) { throw new ServletException(e); } } else if (req.getParameter("token") != null && req.getParameter("returl") == null) { resp.setContentType("text/plain"); TokenInfo ti = tokenMap.get(req.getParameter("token")); if (ti != null && ti.getUserLogin() != null) { resp.getWriter().print(ti.getUserLogin()); } else { resp.setStatus(401); resp.getWriter().print("Invalid token"); } } else { resp.getWriter().print("invalid syntax, please consult source code for org.aperteworkflow.gui.auth.GenerateTokenServlet"); } } private static synchronized HashMap<String, TokenInfo> getTokenMap(ServletContext sc) { HashMap<String,TokenInfo> tokenMap = (HashMap<String, TokenInfo>) sc.getAttribute(TOKEN_MAP); if (tokenMap == null) { tokenMap = new HashMap<String, TokenInfo>(); sc.setAttribute(TOKEN_MAP, tokenMap); } return tokenMap; } private static synchronized void cleanupTokens(HashMap<String, TokenInfo> tokenMap) { Collection<String> tokens = new HashSet<String>(tokenMap.keySet());//avoid concurrent modification exception, please! for (String currentToken : tokens) { TokenInfo tokenInfo = tokenMap.get(currentToken); if (tokenInfo != null) { int validityTime = tokenInfo.getValidityTime(); Date creationDate = tokenInfo.getCreationDate(); Calendar validityCalendar = Calendar.getInstance(); validityCalendar.setTime(creationDate); validityCalendar.add(Calendar.MINUTE, validityTime); if (new Date().after(validityCalendar.getTime())) { tokenMap.remove(currentToken); } } else { tokenMap.remove(currentToken); } } } public static String toHex(byte[] bytes) { BigInteger bi = new BigInteger(1, bytes); return String.format("%0" + (bytes.length << 1) + "X", bi); } }