GitHub地址

码云地址

Feign可以调用其他微服务的api接口,当其他服务没有权限验证的时候可以直接调用,但是调用服务存在权限拦截的话,就无法正常调用。本文讲的就是Feign调用认证api的一种方式。

首先新建一个fp-resouce-feign模块做调用测试,本模块不加OAuth2的拦截。

pom.xml增加常规依赖以及Feign的依赖

 	<!--Feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

在启动文件上加上@EnableFeignClients 注解表示启用Feign; 新建一个简单的Feign调用,这里我们调用manager服务,该服务增加了SpringSecurityOAuth2的权限拦截

@FeignClient(value = "manager")
public interface ResourceManagerFeignClient {
    @GetMapping(value = "/auth/hello")
    String hello();
}

对有权限处理的服务接口直接调用会造成调用时出现http 401未授权的错误,继而导致最终服务的http 500内部服务器错误 请求示例如图:

SpringSecurityOAuth2(9) feign 微服务间调用 token验证-LMLPHP

最方便的方案就是咋请求头上加上认证token信息,Feign 有一个接口 RequestInterceptor,做一些简单的添加token处理即可调用服务接口:

@Configuration
public class FeignConfig implements RequestInterceptor {

    public static String TOKEN_HEADER = "authorization";

    @Override
    public void apply(RequestTemplate template) {
        template.header(TOKEN_HEADER, getHeaders(getHttpServletRequest()).get(TOKEN_HEADER));
    }

    private HttpServletRequest getHttpServletRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
            return null;
        }
    }

    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }
}

结果示例:

SpringSecurityOAuth2(9) feign 微服务间调用 token验证-LMLPHP

至此Feign调用有权限服务接口的简单实现完成。

05-10 09:12