Har*_*har 7 java spring-boot microservices feign
我关注了这个博客并创建了一些微服务:Eureka-server、Auth-service、Zuul-service、Gallery-service、Image-service。从画廊服务中,我想使用 Feign-Client 调用 auth-service API 该 url 不需要身份验证,但客户端抛出 FeignException$Unauthorized 我正在使用 JWT 令牌进行身份验证。
//AuthServerProxy.java
@FeignClient(name = "auth-service")
@RibbonClient(name = "auth-service")
public interface AuthServiceProxy {
    @PostMapping("/auth/authenticate")
    public ResponseEntity<?> authenticate(@RequestBody UserEntity userEntity);
    @GetMapping("/auth/register")
    public String test();
}
控制器 - 画廊服务
@Autowired
    AuthServiceProxy authServiceProxy;
    @GetMapping("/test")
    public String test(){
        UserEntity userEntity = new UserEntity();
        userEntity.setUsername("admin");
        userEntity.setPassword("admin");
        ResponseEntity<?> responseEntity = authServiceProxy.authenticate(userEntity);
        System.out.println(responseEntity.getStatusCode());
        return responseEntity.toString();
    }
    @GetMapping("/test/str")
    public String testStr(){
        return authServiceProxy.test();
    }
安全配置 - ZuulServer、Auth-Service
.antMatchers(HttpMethod.POST, "/auth/authenticate").permitAll()
这是错误日志
ERROR 1123 --- [nio-8100-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException$Unauthorized: status 401 reading AuthServiceProxy#authenticate(UserEntity)] with root cause
feign.FeignException$Unauthorized: status 401 reading AuthServiceProxy#authenticate(UserEntity)
at feign.FeignException.errorStatus(FeignException.java:94) ~[feign-core-10.2.3.jar:na]
    at feign.FeignException.errorStatus(FeignException.java:86) ~[feign-core-10.2.3.jar:na]
    at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:93) ~[feign-core-10.2.3.jar:na]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:149) ~[feign-core-10.2.3.jar:na]
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.2.3.jar:na]
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.2.3.jar:na]
    at com.sun.proxy.$Proxy101.authenticate(Unknown Source) ~[na:na]
    at com.test.gallery.Controller.test(Controller.java:47) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
...
非常感谢任何帮助。TIA
Feign 不知道应该传递给目标服务的授权。不幸的是,您需要自己处理这个问题。下面是一个可以帮助您的 java 类
@Component
public class FeignClientInterceptor implements RequestInterceptor {
     private static final String AUTHORIZATION_HEADER = "Authorization";
       private static final String BEARER_TOKEN_TYPE = "Bearer";
    
    
       @Override
        public void apply(RequestTemplate template) {
            SecurityContext securityContext = SecurityContextHolder.getContext();
            Authentication authentication = securityContext.getAuthentication();
            if (authentication != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
                OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
                template.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
            }
        }
小智 1
听起来问题可能是您没有将 @EnableResourceServer 附加到您的 Auth-Service 。
\n\n如果没有该注释,任何不属于 spring security 包的端点(例如 /oauth/token、/oauth/check_token)将自动需要授权。
\n\n此外,您可能需要添加与此类似的 ResourceServerConfigurerAdapter 以确保资源端点配置为允许所有端点,如下所示:
\n\n@Configuration\n@EnableResourceServer\npublic class ResourceServerConfig extends ResourceServerConfigurerAdapter {\n\n    private final TokenStore tokenStore;\n\n    public ResourceServerConfig(TokenStore tokenStore) {\n        this.tokenStore = tokenStore;\n    }\n\n    @Override\n    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {\n        resources.tokenStore(tokenStore);\n    }\n\n    @Override\n    public void configure(HttpSecurity http) throws Exception {\n        http\n                .authorizeRequests()\n                .antMatchers(HttpMethod.POST).permitAll()\n                .and()\n                .logout().disable()\n                .csrf().disable();\n    }\n}\n*******编辑*********
\n\n如果您\xe2\x80\x99能够从浏览器中的请求获得正常响应,但不能假冒,那么您的问题很可能是您的假冒客户端\xe2\x80\x99t指向正确的端点。通常您会收到 404 错误,但由于 API 是安全的,您会收到 401,因为它甚至不允许您知道什么是有效端点,除非您经过身份验证或者它\xe2\x80\x99是一个不安全的端点
\n\n如果您的 AuthServiceProxy feign 客户端使用 zuul-server 而不是 auth-service,那么您可以将日志记录添加到 zuul 过滤器中,以查看成功和不成功的请求。从那里进行必要的更改,使您的代理请求与您从浏览器发出的请求匹配,您应该可以开始了
\n| 归档时间: | 
 | 
| 查看次数: | 19196 次 | 
| 最近记录: |