Spring cloud zuul service gateway implementation

Keywords: Google Apache less Java

authentication

Next, write a simple authentication

The request must carry the token parameter. If there is no token, the request will be rejected

among

  • filterType -- filter type, use pre? Type here
  • filterOrder -- filter order. The smaller the value is, the higher the priority is. Here it is placed in front of the pre ﹣ determination ﹣ filter ﹣ order
  • shouldFilter--fill true
  • run -- specific operation of filter
package com.viki.apigateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * Prefilter, access is allowed only with token
 * @Author Sakura
 * @Date 13/11/2019
 **/
@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //Filter order, before the pre filter (the lower the value, the higher the priority)
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //Obtained from url parameter, cookie and header
        String token = request.getParameter("token");
        if(StringUtils.isEmpty(token)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }

        return null;
    }
}

Current limiting

Limit traffic to avoid unnecessary losses due to excessive requests.

In the house pre filter, the timing is called before the request is forwarded. If pre has multiple filters, it should be placed at the forefront.

There are many current limiting strategies. Here, token bucket is selected

The dealer adds a token to the token bucket at a fixed rate. If the token bucket is full, it will be discarded. If it is not full, it will continue to put. When the request comes, the token will be taken from the bucket. If it is obtained, the token will be released. If it is not obtained, the request will be rejected.

Create a RateLimitFilter file and use Google integrated token bucket

package com.viki.apigateway.filter;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import com.viki.apigateway.exception.RateLimitException;
import org.springframework.stereotype.Component;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

/**
 * Current limiting
 * @Author Sakura
 * @Date 13/11/2019
 **/
@Component
public class RateLimitFilter extends ZuulFilter {

    //google token bucket, 100 per second
    private static RateLimiter RATE_LIMITERR = RateLimiter.create(100);

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //Highest priority (less than minimum)
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {

        if(!RATE_LIMITERR.tryAcquire()){
            throw new RateLimitException();
        }
        return null;
    }
}

Cross domain

There is a homology policy in ajax, and violating the homology policy will lead to homology problem. There are two ways to solve the problem of homology

  • Use @ CrossOrigin annotation, but this is for methods
  • Unified configuration in zuul for all projects

zuul unified configuration method

package com.viki.apigateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;

/**
 * Cross domain configuration
 * @Author Sakura
 * @Date 13/11/2019
 * C - Cross   O - Origin  R - Resource  S - Sharing
 **/
@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true);  //Allow cookie s to cross domains
        config.setAllowedHeaders(Arrays.asList("*")); //Allow all headers
        config.setAllowedMethods(Arrays.asList("*")); //Allow all methods, GET,POST, etc
        config.setAllowedOrigins(Arrays.asList("*"));  //Original domain, such as www.viki.com
        config.setMaxAge((long) 3001); //Cache time, no longer check in the specified time period

        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

 

159 original articles published, 59 praised, 90000 visitors+
Private letter follow

Posted by Tubbietoeter on Mon, 17 Feb 2020 02:42:43 -0800