Previously we talked about how to ensure the authentication of each microservice before calling

  • How can calls between microservices be secured in Spring Cloud
  • How to guarantee the security of calls between microservices in Spring Cloud (Part 2)

The principle is that the token after authentication is obtained from the authentication service before each microservice request, and then the token is carried in the request header, so that the called party can verify the token to determine whether the request is valid

Zuul does not have a zuul pre-filter when a business service calls a business service. So how do we set the zuul pre-filter?

It’s actually quite simple, because the previous calls to our service depend on Feign, so we can build from Feign

If you take a closer look at Feign’s documentation, you’ll notice the following code:

tatic class DynamicAuthTokenTarget<T> implements Target<T> { public DynamicAuthTokenTarget(Class<T> clazz, UrlAndTokenProvider provider, ThreadLocal<String> requestIdProvider); . @Override public Request apply(RequestTemplate input) { TokenIdAndPublicURL urlAndToken = provider.get();if (input.url().indexOf("http") != 0) {
        input.insert(0, urlAndToken.publicURL);
      }
      input.header("X-Auth-Token", urlAndToken.tokenId);
      input.header("X-Request-ID", requestIdProvider.get());

      returninput.request(); }}... Bank bank = Feign.builder() .target(new DynamicAuthTokenTarget(Bank.class, provider, requestIdProvider));Copy the code

We can set up a request interceptor for Feign to do a few things before calling, adding the request header information

Any native Feign can add interceptors, and that’s certainly possible in Spring Cloud

In the previous article we talked about overriding the default configuration with a custom configuration. We created a FeignConfiguration configuration class to configure Feign’s logging

It’s finally coming in handy today. You can customize an interceptor here

@configuration public class FeignConfiguration {/** * Log level * @return
     */
	@Bean  
    Logger.Level feignLoggerLevel() {  
        returnLogger.Level.FULL; } /** * Create a Feign request blocker that sets authentication tokens before sending requests. Each microservice sets tokens into environment variables to achieve universal * @return
     */
    @Bean
    public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        returnnew FeignBasicAuthRequestInterceptor(); }} / Feign request interceptor * * * * @ author yinjihuan * @ the create the 2017-11-10 they * * / public class FeignBasicAuthRequestInterceptor implements RequestInterceptor { publicFeignBasicAuthRequestInterceptor() {

    }

    @Override
    public void apply(RequestTemplate template) {
        template.header("Authorization", System.getProperty("fangjia.auth.token")); }}Copy the code

The general step is to set the token by setting Feign’s interceptor. Since this is universal, all token values are passed through environment variables

Each microservice only needs to set the obtained token information into the environment variable

 System.setProperty("fangjia.auth.token", token);
Copy the code

Last time we talked about how to get the token automatically, we did it through a scheduled task to periodically refresh, and we also created an AuthService to get the token

In today’s optimization, because this also needs to be generic, so directly removed Service

/** * @author yinjihuan * @create 2017-11-09 15:39 **/ @Component Public class TokenScheduledTask { private static Logger logger = LoggerFactory.getLogger(TokenScheduledTask.class); public final static long ONE_Minute = 60 * 1000 * 60 * 20; @Autowired private AuthRemoteClient authRemoteClient; ** ** Update Token */ @scheduled (fixedDelay = ONE_Minute) public void */ ** * Update Token */ @scheduled (fixedDelay = ONE_Minute) public voidreloadApiToken() {
        String token = this.getToken();
        while (StringUtils.isBlank(token)) {
            try {
                Thread.sleep(1000);
                token = this.getToken();
            } catch (InterruptedException e) {
                logger.error("", e);
            }
        }
        System.setProperty("fangjia.auth.token", token);
    }

    public String getToken() {
        AuthQuery query = new AuthQuery();
        query.setAccessKey("1");
        query.setSecretKey("1");
        ResponseData response = authRemoteClient.auth(query);
        return response.getData() == null ? "": response.getData().toString(); }}Copy the code

By now, each micro service direct security certification is over, it is not troublesome to use, the following summary

  • Define a microservice for authentication that can have user information, business independent, and provide an authentication interface
  • Define JWT utility classes that provide methods for generating tokens and checking tokens, public
  • Define authentication token filter, public
  • The interception can be achieved by registering filters in microservices that require authentication, or it can be made public, where all require authentication
  • TokenScheduledTask is configured on the caller to implement the timed refresh token, which can also be made public

If authentication is not required, then no blocking filter is registered and no TokenScheduledTask is used, with no intrusion into the business code

For specific code, please refer to my Github:

Github.com/yinjihuan/s…

For more technology sharing, please pay attention to wechat public number: Ape World