SpringClound微服务调用安全

微服务调用安全有两个方面

1.客户端调用微服务的安全问题,通过zuul的网关去解决。当是我们想在ueurka内建一个小团体,所以请求头加了token(相当于多加了一道锁子)

2.微服务之间的调用的安全问题,通过fegin调用,解决思路是在调用时请求头加上token,让被调用方验证token的有效性

所以以上两种安全可以用同一种思路去解决,简化流程,提高安全

一、被调用方的过滤器的解决

在启动类中添加

	@Bean
	public FilterRegistrationBean testFilterRegistration() {
		FilterRegistrationBean registration = new FilterRegistrationBean(new LoginFilter());
		List<String> urlPatterns = new ArrayList<String>();

		urlPatterns.add("/*");

		registration.setUrlPatterns(urlPatterns);
		registration.setEnabled(true);  //过滤器的开关
		return registration;
	}

过滤类

import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LoginFilter implements Filter {


    protected static List<Pattern> patterns = new ArrayList<Pattern>();




    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext());

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        String usertoken = httpRequest.getHeader("usertoken");
        String url = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());


        String[] regex=new String[10] ;
        regex[0]="^login.*$";
        /**
         * swagger的url
         */
        regex[1]="^v2.*$";
        regex[2]="^webjars.*$";
        regex[3]="^swagger.*$";
        for (int i=0;i<=3;i++) {
            patterns.add(Pattern.compile(regex[i]));
        }
        if (url.startsWith("/") && url.length() > 1) {
            url = url.substring(1);
        }

        if (isInclude(url)){
            filterChain.doFilter(httpRequest, httpResponse);
            return;
        }else {
            //过滤条件的判断和业务处理


}
    }

    @Override
    public void destroy() {

    }
    private boolean isInclude(String url) {
        for (Pattern pattern : patterns) {
            Matcher matcher = pattern.matcher(url);
            if (matcher.matches()) {
                return true;
            }
        }
        return false;
    }
}

二、在调用方通过fegin访问

接口类

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

@Component
@FeignClient(value = "bbb")
public interface ServiceClient {

    @RequestMapping("/xxx/selectone")
    String printf();
}

controller类

@RestController
public class ConsumerController {

    @Autowired
    private ServiceClient serviceClient;

    @RequestMapping("/test")   
    public String test(){   //可以在此处获得请求头信息
         return serviceClient.printf();
    }
}

三、核心配置

调用方的fegin配置类

@Configuration
public class FeignConfiguration {
    /**
     * 日志级别
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }


    /**
     * 创建Feign请求拦截器,在发送请求前设置认证的token,各个微服务将token设置到环境变量中来达到通用
     * @return
     */
    @Bean
    public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new FeignBasicAuthRequestInterceptor();
    }



}

调用方的请求拦截类

import feign.RequestInterceptor;
import feign.RequestTemplate;

/**
 * Feign请求拦截器
 * @author yinjihuan
 * @create 2017-11-10 17:25
 **/
public class FeignBasicAuthRequestInterceptor  implements RequestInterceptor {

    public FeignBasicAuthRequestInterceptor() {

    }

    @Override
    public void apply(RequestTemplate template) {
        System.setProperty("auth.token","abc");  //这个可以通过其他类来设置到全局变量中
        template.header("usertoken", System.getProperty("auth.token"));
    }
}

推荐在调用方的过滤器中将 auth.token  set到全局变量中

或者在调用方的controller中,先获取请求头信息在发送fegin请求

结果 (被调用方拦截)


猜你喜欢

转载自blog.csdn.net/fwk19840301/article/details/80369101