一、黑名单拦截spring
二、参数验签数据库
三、Api接口权限验证设计模式
一、继承ZuulFilter方法,实现业务逻辑api
@Component @Slf4j public class GatewayFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { // 改成true,才会走run方法 return true; } /** * 请求以前拦截处理业务逻辑 * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); // 1.获取请求对象 HttpServletRequest request = ctx.getRequest(); // 2.获取响应对象 HttpServletResponse response = ctx.getResponse(); // 3.获取客户端真实ip地址 String ipAddr = IpUtil.getIpAddr(request); if (StringUtils.isEmpty(ipAddr)) { resultError(ctx, "未可以获取到ip地址"); } // 4.动态获取黑名单列表,判断是黑名单,设置网关响应为false if("127.0.0.1".equals(ipAddress)){ resultError(ctx, "ip:" + ipAddress + ",Insufficient access rights"); } // 5.传递参数签名拦截 Map<String, String> verifyMap = SignUtil.toVerifyMap(request.getParameterMap(), false); if(!SignUtil.verify(verifyMap)){ resultError(ctx, "ip:" + ipAddress + ",Sign fail"); } // 6.api权限验证 String servletPath = request.getServletPath(); String accessToken = request.getParameter("accessToken");if (StringUtils.isEmpty(accessToken)) { resultError(ctx, "AccessToken cannot be empty"); } // 调用接口验证accessToken是否失效 BaseResponse<JSONObject> appInfo = verificaCodeServiceFeign.getAppInfo(accessToken);if (!isSuccess(appInfo)) { resultError(ctx, appInfo.getMsg()); } return null; } /** * 错误返回 * @param ctx * @param code * @param errorMsg */ private void resultError(RequestContext ctx, String errorMsg) { ctx.setResponseStatusCode(401); // 网关响应为false 不会转发服务 ctx.setSendZuulResponse(false); ctx.setResponseBody(errorMsg); }
一、基于建造者设计模式封装: 网关权限控制app
public interface GatewayBuild { /** * 黑名单拦截 */ Boolean blackBlock(RequestContext ctx, String ipAddress, HttpServletResponse response); /** * 参数验签 */ Boolean paramsValidate(RequestContext ctx, String ipAddress, HttpServletRequest request); /** * api权限控制 * * @return */ Boolean apiAuthorize(RequestContext ctx, HttpServletRequest request); }
二、基于建造者设计模式封装: 参数验证build,业务逻辑的实现ide
@Slf4j @Component public class VerificationBuild implements GatewayBuild { @Override public Boolean blackBlock(RequestContext ctx, String ipAddress, HttpServletResponse response) { // 4.从数据库动态读取,判断是黑名单,设置网关响应为false if("127.0.0.1".equals(ipAddress)){ resultError(ctx, "ip:" + ipAddress + ",Insufficient access rights"); return false; } log.info(">>>>>>ip:{},验证经过>>>>>>>", ipAddress); return true; } @Override public Boolean paramsValidate(RequestContext ctx, String ipAddress, HttpServletRequest request) { // 5.外网传递参数签名拦截 Map<String, String> verifyMap = SignUtil.toVerifyMap(request.getParameterMap(), false); if(!SignUtil.verify(verifyMap)){ resultError(ctx, "ip:" + ipAddress + ",Sign fail"); return false; } return true; } @Override public Boolean apiAuthorize(RequestContext ctx, HttpServletRequest request) { String servletPath = request.getServletPath(); // 内部服务调用不须要accessToken验证,若是public开头,表示受权方访问接口 if (!servletPath.substring(0, 7).equals("/public")) { return true; } String accessToken = request.getParameter("accessToken"); log.info(">>>>>accessToken验证:" + accessToken); if (StringUtils.isEmpty(accessToken)) { resultError(ctx, "AccessToken cannot be empty"); return false; } // 调用接口验证accessToken是否失效 BaseResponse<JSONObject> appInfo = verificaCodeServiceFeign.getAppInfo(accessToken); log.info(">>>>>>data:" + appInfo.toString()); if (!isSuccess(appInfo)) { resultError(ctx, appInfo.getMsg()); return false; } return true; } /** * 网关拦截 * @param ctx * @param code * @param errorMsg */ private void resultError(RequestContext ctx, String errorMsg) { ctx.setResponseStatusCode(401); // 网关响应为false 不会转发服务 ctx.setSendZuulResponse(false); ctx.setResponseBody(errorMsg); } }
三、基于建造者设计模式封装: 链接Buildui
@Component public class GatewayDirector { @Resource(name = "VerificationBuild") private GatewayBuild gatewayBuild; /** * 链接建造者 * @param ctx * @param ipAddress * @param response * @param request */ public void direcot(RequestContext ctx, String ipAddress, HttpServletResponse response, HttpServletRequest request){ // 1.黑名单 Boolean boolBlackBlock = gatewayBuild.blackBlock(ctx, ipAddress, response); if(!boolBlackBlock){ return; } // 2.参数验证 Boolean boolParamsValidate = gatewayBuild.paramsValidate(ctx, ipAddress, request); if(!boolParamsValidate){ return; } // 3.api权限控制 Boolean boolApiAuthorize = gatewayBuild.apiAuthorize(ctx, request); if(!boolApiAuthorize){ return; } } }
四、网关过滤器中调用spa
@Override public Object run() throws ZuulException { // 设计模式一: 基于建造者模式封装 RequestContext ctx = RequestContext.getCurrentContext(); // 1.获取请求对象 HttpServletRequest request = ctx.getRequest(); // 2.获取响应对象 HttpServletResponse response = ctx.getResponse(); // 3.获取客户端真实ip地址 String ipAddr = IpUtil.getIpAddr(request); if (StringUtils.isEmpty(ipAddr)) { resultError(ctx, "未可以获取到ip地址"); } // 4.基于建造者模式封装: 进行请求限制 gatewayDirector.direcot(ctx,ipAddr,response,request); return null; }