spring boot使用自定义过滤器实现接口认证
创始人
2024-03-08 14:53:32

spring boot使用自定义过滤器实现接口认证

  • 自定义过滤器
  • 创建FilterConfig类
  • 加密 解密 验证CipherFilter
  • 其他工具类
    • AES 128 加密工具
    • bean未加载前获取bean
  • 接口效果
    • swagger访问
    • Apipost 错误请求
    • Apipost 正确请求

自定义过滤器

创建MyFilter 类 去实现Filter接口
根据业务逻辑,来覆写doFilter方法


import com.alibaba.fastjson.JSONObject;
import com.shxp.project.common.entity.R;
import com.shxp.project.common.entity.SpringBeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;public class MyFilter implements Filter {final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MyFilter.class);@Autowiredprivate CipherFilter cipherFilter;@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {// 打印请求信息HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) res;logger.info("------------- LogFilter 开始 -------------");logger.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());logger.info("远程地址: {}", request.getRemoteAddr());long startTime = System.currentTimeMillis();// 验证是否成功默认falseboolean isFilter = false;// new一个报错返回实体 R r = new R();try {// 判断引入的验证方法是否为空,如果为空通过SpringBean的方式引进if (cipherFilter == null) {cipherFilter = SpringBeanFactoryUtils.getBean(CipherFilter.class);}// 验证方法isFilter = cipherFilter.handle(request, response);} catch (Exception ex) {
//            e.printStackTrace();r.setCode(500);r.setMsg(ex.getMessage());PrintWriter writer = null;OutputStreamWriter osw = null;try {osw = new OutputStreamWriter(response.getOutputStream(), "UTF-8");writer = new PrintWriter(osw, true);String json = JSONObject.toJSONString(r);writer.write(json);writer.flush();writer.close();osw.close();} catch (UnsupportedEncodingException e) {logger.error("过滤器返回信息失败:" + e.getMessage(), e);} catch (IOException e) {logger.error("过滤器返回信息失败:" + e.getMessage(), e);} finally {if (null != writer) {writer.close();}if (null != osw) {osw.close();}}return;}logger.info("------------- LogFilter 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);// 如果验证通过执行if (isFilter) {chain.doFilter(req, res);}}public void init(FilterConfig filterConfig) {}public void destroy() {}
}

创建FilterConfig类

该配置类用于配置你要过滤的过滤路径

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration //定义此类为配置类,必须增加
public class FilterConfig {@Beanpublic FilterRegistrationBean myFilterRegistrationBean() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());//添加过滤器路径filterRegistrationBean.addUrlPatterns("/workflow/*");filterRegistrationBean.addUrlPatterns("/system/yyxt/*");//        filterRegistrationBean.addUrlPatterns("/login/*");return filterRegistrationBean;}}

加密 解密 验证CipherFilter

CipherFilter 中主要对过滤接口Header中的值进行:非空判断、数据解密、数据认证

 	public boolean handle(HttpServletRequest request, HttpServletResponse response) throws Exception {AuthParam authorityParam = new AuthParam();authorityParam.setModuleId(request.getHeader("moduleId"));authorityParam.setNonce(request.getHeader("nonce"));authorityParam.setSignature(request.getHeader("signature"));return handle0(authorityParam);}public boolean handle0(AuthParam authorityParam) throws Exception {String moduleId = authorityParam.getModuleId();if (StringUtils.isBlank(moduleId)) {throw new Exception("moduleId 不允许为空!");}// 查询所有外部对接系统信息Map map = subSystemService.getSubSystemMap();SysYyxtVo subSystem = map.get(moduleId);if (subSystem == null) {throw new Exception("无法识别的moduleId !");}String nonce = authorityParam.getNonce();if (StringUtils.isBlank(nonce)) {throw new Exception("nonce 不允许为空!");}String signature = authorityParam.getSignature();if (StringUtils.isBlank(signature)) {throw new Exception("signature 不允许为空!");}// 对数据进行加密判断是否一致// moduleKey 是本系统对外部系统的密钥String sig2 = AESUtils.sha1(subSystem.getModulekey(), nonce);if (!signature.equals(sig2)) {throw new Exception("验证不通过,请检查是否持有正确的moduleKey!");}return true;}

其他工具类

AES 128 加密工具


import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.util.Base64Utils;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;/*** AES 128 加密工具*/
public class AESUtils {public final static String ENCODING="UTF-8";public final static String KEY_AES="AES";public static KeyGenerator kgen;static {try {kgen = KeyGenerator.getInstance("AES");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}/*** AES128 加密* @param content 内容* @param password 密钥* @return 加密后的结果*/public static String aes128Encrypt(String content, String password){try{Cipher cipher = Cipher.getInstance(KEY_AES);byte[] byteContent = content.getBytes(ENCODING);SecretKeySpec secretKeySpec = getSecretKeySpec(password);cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);byte[] result = cipher.doFinal(byteContent);return Base64Utils.encodeToString(result);}catch (Exception e){e.printStackTrace();}return null;}/*** AES128 解密* @param content 内容* @param password 密钥* @return 解密后的结果*/public static String aes128Decrypt(String content, String password){try{Cipher cipher = Cipher.getInstance(KEY_AES);SecretKeySpec secretKeySpec = getSecretKeySpec(password);cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);byte[] byteContent = Base64Utils.decodeFromString(content);byte[] result = cipher.doFinal(byteContent);return new String(result,ENCODING);}catch (Exception e){e.printStackTrace();}return null;}private static SecretKeySpec getSecretKeySpec(String password) throws UnsupportedEncodingException {kgen.init(128, new SecureRandom(password.getBytes(ENCODING)));return new SecretKeySpec(kgen.generateKey().getEncoded(), KEY_AES);}public static String md5(String text, String key) throws Exception{String encodeStr = DigestUtils.md5Hex(text + key);return encodeStr;}public static String sha1(String text, String key) throws Exception{String encodeStr = DigestUtils.sha1Hex(text + key);return encodeStr;}
}

bean未加载前获取bean

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/*** bean未加载前获取bean*/
@Component
public class SpringBeanFactoryUtils implements ApplicationContextAware {private static ApplicationContext context = null;//获取beanpublic static  T getBean(Class type) {return context.getBean(type);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if (SpringBeanFactoryUtils.context == null) {SpringBeanFactoryUtils.context = applicationContext;}}
}

接口效果

swagger访问

我们发现通过swagger访问已经不行了
在这里插入图片描述

Apipost 错误请求

我们用apipost 故意写错moduleId
在这里插入图片描述

Apipost 正确请求

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...