Java 如何向假客户端添加请求拦截器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40262132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add a request interceptor to a feign client?
提问by Gustavo
I want every time when I make a request through feign client, to set a specific header with my authenticated user.
我希望每次通过 feign 客户端发出请求时,都为我的经过身份验证的用户设置一个特定的标头。
This is my filter from which I get the authentication and set it to the spring security context:
这是我从中获取身份验证并将其设置为 spring 安全上下文的过滤器:
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients
public class PerformanceApplication {
@Bean
public Filter requestDetailsFilter() {
return new RequestDetailsFilter();
}
public static void main(String[] args) {
SpringApplication.run(PerformanceApplication.class, args);
}
private class RequestDetailsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String userName = ((HttpServletRequest)servletRequest).getHeader("Z-User-Details");
String pass = ((HttpServletRequest)servletRequest).getHeader("X-User-Details");
if (pass != null)
pass = decrypt(pass);
SecurityContext secure = new SecurityContextImpl();
org.springframework.security.core.Authentication token = new UsernamePasswordAuthenticationToken(userName, pass);
secure. setAuthentication(token);
SecurityContextHolder.setContext(secure);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
private String decrypt(String str) {
try {
Cipher dcipher = new NullCipher();
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
} catch (java.io.IOException e) {
}
return null;
}
}
This is my feign client:
这是我的假客户:
@FeignClient("holiday-client")
public interface EmailClient {
@RequestMapping(value = "/api/email/send", method = RequestMethod.POST)
void sendEmail(@RequestBody Email email);
}
And here I have a request interceptor:
在这里我有一个请求拦截器:
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
private String headerValue;
public FeignRequestInterceptor() {
}
public FeignRequestInterceptor(String username, String password) {
this(username, password, ISO_8859_1);
}
public FeignRequestInterceptor(String username, String password, Charset charset) {
checkNotNull(username, "username");
checkNotNull(password, "password");
this.headerValue = "Basic " + base64encode((username + ":" + password).getBytes(charset));
}
private static String base64encode(byte[] bytes) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(bytes);
}
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("Authorization", headerValue);
}
}
I don't know how to configure this interceptor to my client and how to set the header with the username and password. How can I accomplish that ?
我不知道如何将此拦截器配置到我的客户端,以及如何使用用户名和密码设置标头。我怎样才能做到这一点?
回答by Aleksandr Erokhin
You don't really need your own implementation of the FeignRequestInterceptor
as there is already BasicAuthRequestInterceptorin the feign.auth
package that does exactly the same.
您真的不需要自己的实现,FeignRequestInterceptor
因为包中已经有BasicAuthRequestInterceptor的feign.auth
功能完全相同。
With this said, you basically have almost everything set up already. All is left to do is to define the basicAuthRequestInterceptor
bean with specific username and password:
话虽如此,您基本上已经设置了几乎所有内容。剩下要做的就是定义basicAuthRequestInterceptor
具有特定用户名和密码的bean:
@Bean
public RequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("username", "password");
}