场景:有一些内部的接口知识被自己的服务调用,自己的服务有几个固定的常用域名,不希望被其他的外部来源恶意访问,因此需要在请求之前进行验证,在controller包下面定义一个rpc包,里面的接口不让外部访问。
注解加切面方式方式(使用时只需要在需要判断的类上面写上自己定义的注解@Rpccontroller即可):
package com.aiduoka.shop.console.web.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author by zengzhiqin
* 2019-08-05
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RpcController {
}
package com.aiduoka.shop.console.web.aspect;
import com.kuaizhan.bizcore.web.entity.BusinessException;
import com.kuaizhan.bizcore.web.entity.ErrorCode;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @author by zengzhiqin
* 2019-08-05
*/
@Aspect
@Component
public class RpcControllerAspect {
String[] domain = {"svc.cluster.local","online.local","test.local","localhost"};
@Pointcut(value = "@within(com.aiduoka.shop.console.web.annotation.RpcController)")
private void controllerMethod() {}
/**
* 访问域名合法化
*/
@Before(value = "controllerMethod()")
public void domainRequiredVerify(){
String domainStr = getRequestDomain();
Boolean isValid = false;
for(int i=0;i<domain.length;i++){
if(domainStr.endsWith(domain[i])){
isValid = true;
break;
}else{
continue;
}
}
if(isValid == false){
throw new BusinessException(ErrorCode.FORBIDDEN);
}
}
private String getRequestDomain(){
//获取到请求的属性
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取到请求对象
HttpServletRequest request = attributes.getRequest();
String domainStr = request.getServerName();
return domainStr;
}
}
拦截器方式:
package com.aiduoka.shop.console.web.aspect;
import com.kuaizhan.bizcore.web.entity.BusinessException;
import com.kuaizhan.bizcore.web.entity.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author by zengzhiqin
* 2019-08-05
*/
@Slf4j
public class RpcIntercepter implements HandlerInterceptor {
String[] domain = {"svc.cluster.local","online.local","test.local","localhost"};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String domainStr = getRequestDomain();
System.out.println(domainStr);
Boolean isValid = false;
for(int i=0;i<domain.length;i++){
if(domainStr.endsWith(domain[i])){
isValid = true;
break;
}else{
continue;
}
}
if(isValid == false){
throw new BusinessException(ErrorCode.FORBIDDEN);
}else{
return true; // 只有返回true才会继续向下执行,返回false取消当前请求*/
}
}
private String getRequestDomain(){
//获取到请求的属性
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取到请求对象
HttpServletRequest request = attributes.getRequest();
String domainStr = request.getServerName();
return domainStr;
}
}
package com.aiduoka.shop.console.web.config;
import com.aiduoka.shop.console.web.aspect.RpcIntercepter;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @author by zengzhiqin
* 2019-08-05
*/
@Configuration
public class RpcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
//获取到请求的属性
registry.addInterceptor(new RpcIntercepter()).addPathPatterns("/rpc/**");
super.addInterceptors(registry);
}
}