一、web.xml:
<filter> <filter-name>fastLoginFilter</filter-name> <filter-class>com.shencai.xf.common.util.FastLoginFilter</filter-class> </filter> <filter-mapping> <filter-name>fastLoginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
配置文件中配置一下访问路径可以用作过滤时候判断,可以直接放行和加密不加密操作:
passUrls=.html;.css;.js;/main/img/;/main/common/;/mlsc-upload/service/sys/file/upload;\
其中,访问静态资源肯定是直接放行不过滤不加密的;
二、java代码:
package com.xxx /** * 用于快速登录的过滤器,仅放行passUrlList中的路径 */ public class FastLoginFilter implements Filter { public static final String TICKET_ID = "ticketId"; public static Logger logger = LoggerUtil.getLoggerByName("system", "loginFilter"); public static String HOME_URL = "/index.html"; public static String LOGIN_URL = "/login.html"; public static String INVALID_URL = "/login.html"; /** * 用于拦截快速登录的请求 */ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; String requestURL = request.getRequestURI(); String retUrl = request.getHeader("Referer"); // 保留未登录websocket通信 if(requestURL.indexOf("/websocket/") == -1){ if(retUrl==null&&!requestURL.equals(LOGIN_URL)||retUrl!=null&&!checkWebReferer(retUrl)){ response.sendRedirect(LOGIN_URL); return; } } if (checkIsPassUrl(requestURL)) { chain.doFilter(req, resp); return; } Object ticketId = request.getSession().getAttribute(TICKET_ID); // Object ticketId = request.getParameter(TICKET_ID); String requestType = request.getHeader("x-requested-with"); String userAgent = request.getHeader("user-agent"); if (ticketId == null) { if ((requestType != null && requestType.equals("XMLHttpRequest")) || checkApp(userAgent)) { writeUnloginInfo((HttpServletResponse) response); } else { response.sendRedirect(LOGIN_URL); } return; } boolean isLogged = this.isLogged(ticketId.toString()); String checkLoginStatus = request.getParameter("checkLoginStatus"); if (StringUtils.isNotNullOrEmpty(checkLoginStatus)) { resp.getWriter().write(String.valueOf(isLogged)); return; } UserInfo userInfo = CacheUtil.getUserByTicket(ticketId.toString(), UserInfo.class); if (userInfo != null && StringUtils.isNotNullOrEmpty(userInfo.getUserId())) { CacheUtil.refreshTicket(ticketId.toString(), userInfo.getUserId()); String token = request.getHeader("token"); String contentType=request.getContentType(); if("1".equals(ConfigUtil.get("aesOpen"))&&"XMLHttpRequest".equals(requestType)&&StringUtils.isNotNullOrEmpty(token) &&"encryption".equals(token)){ //和前台一样的判断是否需要加解密操作 String requestBodyMw = null; String rsaResult=null; try { String p=""; if("application/json".equals(contentType)){ String requestBody = getRequestParam((HttpServletRequest) request); logger.info(requestBody); JSONObject jsonObject=JSONObject.parseObject(requestBody); p=jsonObject.getString("p"); //获取前台传的加密之后的参数p }else{ p=request.getParameter("p"); } requestBodyMw = CryptionUtil.aesDecrypt(p.trim(), ConfigUtil.get("aecKey")); //先将请求参数进行aes解密 rsaResult= RSAEncryptUtils.decrypt(requestBodyMw); //再将前台传的参数进行RSA解密,步骤与前台相反 } catch (Exception e) { writeUnloginInfo((HttpServletResponse) response); return; } WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse) response); //封装的响应对象 WrapperedRequest wrapRequest = new WrapperedRequest((HttpServletRequest) request, rsaResult); //封装的请求对象 chain.doFilter(wrapRequest, wrapResponse); //调用自己框架的过滤器方法,获取当前用户之类的 byte[] data = wrapResponse.getResponseData(); String resData=new String(data, "utf-8"); JSONObject resultObj=new JSONObject(); try { resultObj.put("data",CryptionUtil.aesEncrypt(resData, ConfigUtil.get("aecKey"))); //返回的参数也是aes加密的 } catch (Exception e) { e.printStackTrace(); } writeResponse(response, resultObj.toJSONString()); return; } } else { if ((requestType != null && requestType.equals("XMLHttpRequest")) || checkApp(userAgent)) { writeUnloginInfo((HttpServletResponse) response); } else { response.sendRedirect(INVALID_URL); } return; } chain.doFilter(req, resp); return; } private boolean checkWebReferer(String retUrl){ boolean flag=false; String configWebReferer=ConfigUtil.get("webReferer"); String[] webRefererArr=configWebReferer.split(","); for(int i=0;i<webRefererArr.length;i++){ if(retUrl.startsWith(webRefererArr[i])){ flag=true; break; } } return flag; } private void writeResponse(ServletResponse response, String responseString) throws IOException { PrintWriter out = response.getWriter(); response.setContentLength(responseString.length()); out.print(responseString); out.flush(); out.close(); } private String getRequestParam(HttpServletRequest request){ ServletInputStream inputStream = null; StringBuilder sb = new StringBuilder(); try { inputStream = request.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); String line = ""; while ((line = br.readLine()) != null) { sb.append(line); } } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } // 获取请求路径,如果是:/fastLoginWS,则直接放行 public boolean checkIsPassUrl(String requestURL) throws IOException, ServletException { boolean isPass = false; if (StringUtils.isNotNullOrEmpty(requestURL)) { // 判断访问的路径是否为路径放行集合中的路径,如果含有,则直接放行 for (String url : ConfigUtil.PASS_URLS) { //配置文件中可以配置一下访问路径,用于不用过滤,不用进行加解密操作等 if (requestURL.indexOf(url) != -1) { isPass = true; break; } } } return isPass; } private boolean checkApp(String userAgent) { if (userAgent != null) { if (userAgent.indexOf("okhttp") != -1) { return true; } if (userAgent.indexOf("Darwin") != -1) { return true; } if(userAgent.indexOf("MicroMessenger")>-1){ return true; } } return false; } private void writeUnloginInfo(HttpServletResponse response) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); //设置状态码 response.setContentType(MediaType.APPLICATION_JSON_VALUE); //设置ContentType response.setCharacterEncoding("UTF-8"); //避免乱码 response.setHeader("Cache-Control", "no-cache, must-revalidate"); try { response.getWriter().write("{\"statusCode\":1001,\"loginUrl\":\"" + LOGIN_URL + "\",\"success\":false,\"msg\":\"用户身份已经失效! \"}"); } catch (IOException e) { logger.error("与客户端通讯异常:" + e.getMessage(), e); } } public static boolean isLogged(String ticketId) { if (ticketId == null) { return false; } else { return CacheUtil.isExist(CacheUtil.PREFIX_TICKET_USER.concat(ticketId)); } } public void init(FilterConfig arg0) throws ServletException { String homeUrl = ConfigUtil.get("homeUrl"); if (StringUtils.isNotNullOrEmpty(homeUrl)) { HOME_URL = homeUrl; } String loginUrl = ConfigUtil.get("loginUrl"); if (StringUtils.isNotNullOrEmpty(loginUrl)) { LOGIN_URL = loginUrl; } String invalidUrl = ConfigUtil.get("invalidUrl"); if (StringUtils.isNotNullOrEmpty(invalidUrl)) { INVALID_URL = invalidUrl; } } public void destroy() { } }
封装请求对象WrapperedRequest:
package com.xxx import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; public class WrapperedRequest extends HttpServletRequestWrapper { private String requestBody = null; HttpServletRequest req = null; public WrapperedRequest(HttpServletRequest request) { super(request); this.req = request; } public WrapperedRequest(HttpServletRequest request, String requestBody) { super(request); this.requestBody = requestBody; this.req = request; } /* * (non-Javadoc) * * @see javax.servlet.ServletRequestWrapper#getReader() */ @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new StringReader(requestBody)); } /* * (non-Javadoc) * * @see javax.servlet.ServletRequestWrapper#getInputStream() */ @Override public ServletInputStream getInputStream() throws IOException { return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } private InputStream in = new ByteArrayInputStream( requestBody.getBytes(req.getCharacterEncoding())); @Override public int read() throws IOException { return in.read(); } }; } }
封装响应对象WrapperedResponse:
package com.xxx import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.*; public class WrapperedResponse extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer = null; private ServletOutputStream out = null; private PrintWriter writer = null; public WrapperedResponse(HttpServletResponse resp) throws IOException { super(resp); buffer = new ByteArrayOutputStream();// 真正存储数据的流 out = new WapperedOutputStream(buffer); writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding())); } /** 重载父类获取outputstream的方法 */ @Override public ServletOutputStream getOutputStream() throws IOException { return out; } /** 重载父类获取writer的方法 */ @Override public PrintWriter getWriter() throws UnsupportedEncodingException { return writer; } /** 重载父类获取flushBuffer的方法 */ @Override public void flushBuffer() throws IOException { if (out != null) { out.flush(); } if (writer != null) { writer.flush(); } } @Override public void reset() { buffer.reset(); } /** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */ public byte[] getResponseData() throws IOException { flushBuffer(); return buffer.toByteArray(); } /** 内部类,对ServletOutputStream进行包装 */ private class WapperedOutputStream extends ServletOutputStream { private ByteArrayOutputStream bos = null; public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException { bos = stream; } @Override public void write(int b) throws IOException { bos.write(b); } @Override public void write(byte[] b) throws IOException { bos.write(b, 0, b.length); } @Override public boolean isReady() { return false; } @Override public void setWriteListener(WriteListener writeListener) { } } }
aes加解密的java封装类:
package com.xxx import java.math.BigInteger; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import sun.misc.BASE64Decoder; /** * AES的加密和解密 * @author libo */ public class CryptionUtil { //密钥 (需要前端和后端保持一致) // private static String KEY = ConfigUtil.get("aecKey"); //算法 private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding"; /** * aes解密 * @param encrypt 内容 * @return * @throws Exception */ public static String aesDecrypt(String encrypt) { try { return aesDecrypt(encrypt, ConfigUtil.get("aecKey")); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * aes加密 * @param content * @return * @throws Exception */ public static String aesEncrypt(String content) { try { return aesEncrypt(content, ConfigUtil.get("aecKey")); } catch (Exception e) { e.printStackTrace(); return ""; } } /** * 将byte[]转为各种进制的字符串 * @param bytes byte[] * @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 * @return 转换后的字符串 */ public static String binary(byte[] bytes, int radix){ return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 } /** * base 64 encode * @param bytes 待编码的byte[] * @return 编码后的base 64 code */ public static String base64Encode(byte[] bytes){ return Base64.encodeBase64String(bytes); } /** * base 64 decode * @param base64Code 待解码的base 64 code * @return 解码后的byte[] * @throws Exception */ public static byte[] base64Decode(String base64Code) throws Exception{ return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code); } /** * AES加密 * @param content 待加密的内容 * @param encryptKey 加密密钥 * @return 加密后的byte[] * @throws Exception */ public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); Cipher cipher = Cipher.getInstance(ALGORITHMSTR); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES")); return cipher.doFinal(content.getBytes("utf-8")); } /** * AES加密为base 64 code * @param content 待加密的内容 * @param encryptKey 加密密钥 * @return 加密后的base 64 code * @throws Exception */ public static String aesEncrypt(String content, String encryptKey) throws Exception { return base64Encode(aesEncryptToBytes(content, encryptKey)); } /** * AES解密 * @param encryptBytes 待解密的byte[] * @param decryptKey 解密密钥 * @return 解密后的String * @throws Exception */ public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); Cipher cipher = Cipher.getInstance(ALGORITHMSTR); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES")); byte[] decryptBytes = cipher.doFinal(encryptBytes); return new String(decryptBytes); } /** * 将base 64 code AES解密 * @param encryptStr 待解密的base 64 code * @param decryptKey 解密密钥 * @return 解密后的string * @throws Exception */ public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception { return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey); } /** * 测试 */ public static void main(String[] args) throws Exception { String content = "123"; System.out.println("加密前:" + content); System.out.println("加密密钥和解密密钥:" + ConfigUtil.get("aecKey")); String encrypt = aesEncrypt(content, ConfigUtil.get("aecKey")); System.out.println("加密后:" + encrypt); String decrypt = aesDecrypt(encrypt, ConfigUtil.get("aecKey")); System.out.println("解密后:" + decrypt); } }
RSA加解密的java封装类:
package com.xxx import org.apache.commons.lang3.StringUtils; import javax.crypto.Cipher; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.ArrayList; /** * RSA帮助类 * * @author liww * */ public class RSAEncryptUtils { /** * 模 */ private static String module = "ybhndrU9d3UJzvD8WSS1chQ2ZLcn7Y/ZF0SZFJbdWxkvZYAcICUzfJBF4SecxG+ia9GseNDoQ30q+mSM5Ae1NaAy2bjmR1esS17AyX/TnSvtZIm0ACIVLIM6ShM+ukMj/TEhugarwHXhiHmEd8ZkMrVu4SW2XPgWjX7yPoEKLFs="; /** * 公钥指数 */ private static String exponentString = "AQAB"; private static String delement = "NXVBNhxh5b6GkukadyVbUJg6sgY39qUgiyIKz4ILt5C9FtEUoxA4zNIPMtQkn4pWKOywIHR8mSYatbDgBa5lPxBemwvu5cMHVIh0sD25AL+jXk29alVOIPVTpZ/0TDgy7jd7psYUIX7EO80TnvJIOaNcGUNo060H9qpo19x2iYE="; /** * 生成加密后的字节数组 * * @param value * 待加密字符串 * @param keyXmlString * 加密字符串 * @return */ public static ArrayList<byte[]> encryptToByteArrayList(String value, String keyXmlString) { try { byte[] modulusBytes = org.apache.commons.codec.binary.Base64.decodeBase64(module); byte[] exponentBytes = org.apache.commons.codec.binary.Base64.decodeBase64(exponentString); BigInteger modulus = new BigInteger(1, modulusBytes); BigInteger exponent = new BigInteger(1, exponentBytes); RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent); KeyFactory fact = KeyFactory.getInstance("RSA"); PublicKey pubKey = fact.generatePublic(rsaPubKey); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); int splitLength = 39; ArrayList<byte[]> byteArrayList = new ArrayList<byte[]>(); int i = 0; do { int Length = ((i + 1) * splitLength) >= value.length() ? (value.length() - i * splitLength) : splitLength; byte[] byteArray = cipher.doFinal(value.substring(i * splitLength, Length).getBytes("UTF-8")); byteArrayList.add(byteArray); i++; } while (i * splitLength < value.length()); return byteArrayList; } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA加密字符串 * * @param value * 需要加密的字符串 * @param keyXmlString * 加密key字符串 * @return */ public static String encrypt(String value, String keyXmlString) { ArrayList<byte[]> byteArrayList = encryptToByteArrayList(value, keyXmlString); StringBuilder sb = new StringBuilder(); for (byte[] byteArray : byteArrayList) { sb.append(bytesToHexString(byteArray)); sb.append(","); } if (sb.length() != 0) { sb.delete(sb.length() - 1, sb.length()); } return sb.toString(); } /** * RSA加密字符串 * * @param value * 需要加密的字符串 * @return */ public static String encrypt(String value) { return encrypt(value, null); } public static byte[] Dencrypt(byte[] encrypted) { try { byte[] expBytes = org.apache.commons.codec.binary.Base64.decodeBase64(delement); byte[] modBytes = org.apache.commons.codec.binary.Base64.decodeBase64(module); BigInteger modules = new BigInteger(1, modBytes); BigInteger exponent = new BigInteger(1, expBytes); KeyFactory factory = KeyFactory.getInstance("RSA"); Cipher cipher = Cipher.getInstance("RSA"); RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(modules, exponent); PrivateKey privKey = factory.generatePrivate(privSpec); cipher.init(Cipher.DECRYPT_MODE, privKey); byte[] decrypted = cipher.doFinal(encrypted); return decrypted; } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA解密字节流 * * @param byteArrayList * 需要解密字节流泛型 * @param keyXmlString * 加密key字符串 * @return * @throws UnsupportedEncodingException */ public static String decrypt(ArrayList<byte[]> byteArrayList, String keyXmlString) throws UnsupportedEncodingException { StringBuilder sb = new StringBuilder(); for (byte[] byteArray : byteArrayList) { sb.append(new String(Dencrypt(byteArray), "UTF-8")); } return sb.toString(); } /** * RSA解密字符串 * * @param value * 需要解密的字符串 * @param keyXmlString * 加密key字符串 * @return * @throws UnsupportedEncodingException */ public static String decrypt(String value, String keyXmlString) throws UnsupportedEncodingException { ArrayList<byte[]> byteArrayList = new ArrayList<byte[]>(); if (StringUtils.isNotBlank(value)) { String[] strArray = value.split(","); int byteArrayLength = 0; byte[] byteArray; for (String str : strArray) { byteArrayLength = str.length() / 2; byteArray = new byte[byteArrayLength]; for (int i = 0; i < byteArrayLength; i++) { try { byteArray[i] = Integer.valueOf(str.substring(i * 2, (i + 1) * 2), 16).byteValue(); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } } byteArrayList.add(byteArray); } } return decrypt(byteArrayList, keyXmlString); } /** * RSA解密字符串 * * @param value * 需要解密的字符串 * @return */ public static String decrypt(String value) { try { return decrypt(value, null); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } /** * 将字节数组转换为16进制字符串. 可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。 * * @param src * 字节数组 * @return hex string */ public static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } /** * 将16进制字符串转换为数组 * * @param hexString * 16进制字符串 * @return byte[] */ public static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } /** * 将字符转换为字节 * * @param c * 待转换的字符 * @return byte 转换后的字节 */ private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } }
原文地址:https://www.cnblogs.com/wmqiang/p/11142654.html
时间: 2024-11-09 10:14:57