springboot~某個(gè)接口模擬登錄并同步給feign
功能
- 某個(gè)rest接口是公開的,它的feign服務(wù)的接口需要授權(quán)
- 重寫一個(gè)HttpServletRequestWrapper,實(shí)現(xiàn)模擬登錄之后把header頭進(jìn)行填充
- 接口請(qǐng)求上下文里的token,通過Feign攔截器轉(zhuǎn)給每個(gè)feign請(qǐng)求上下文
- 完成對(duì)feign接口的自動(dòng)授權(quán)訪問
重寫HttpServletRequestWrapper
/**
* 自定義的請(qǐng)求上下文.
*/
public class CustomHttpServletRequest extends HttpServletRequestWrapper {
private Map<String, String> headers = new HashMap<>();
public CustomHttpServletRequest(HttpServletRequest request) {
super(request);
}
public void addHeader(String name, String value) {
headers.put(name, value);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (headers.containsKey(name)) {
value = headers.get(name);
}
return value;
}
@Override
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
names.addAll(headers.keySet());
return Collections.enumeration(names);
}
@Override
public Enumeration<String> getHeaders(String name) {
List<String> list = Collections.list(super.getHeaders(name));
if (headers.containsKey(name)) {
list.add(headers.get(name));
}
return Collections.enumeration(list);
}
}
建立過濾器
@Component
public class CustomFilter implements Filter {
@Autowired
KcUserClient kcUserClient;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
CustomHttpServletRequest request = new CustomHttpServletRequest((HttpServletRequest) servletRequest);
request.addHeader("Authorization", "Bearer " + login().getAccessToken());
filterChain.doFilter(request, servletResponse);
}
public KeycloakAccessToken login() {
// 登陸參數(shù)省略
var result = kcUserClient.login(authTokenRequest);
return result;
}
}
WebMvcConfigurer里注冊(cè)
對(duì)/add接口進(jìn)行配置
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Resource
private CustomFilter customFilter;
@Bean
public FilterRegistrationBean<CustomFilter> initFilterRegistrationBean() {
FilterRegistrationBean<CustomFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(customFilter);
registrationBean.addUrlPatterns("/add");
registrationBean.setOrder(0);
return registrationBean;
}
}
Feign攔截器的配置
/**
* @description: Feign內(nèi)部調(diào)用時(shí)帶上請(qǐng)求頭信息
* 注意:要去yml里面改變hystrix Feign的隔離策為strategy: SEMAPHORE
**/
@Configuration
public class FeignConfiguration implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
template.header(name, values);
}
}
Enumeration<String> bodyNames = request.getParameterNames();
StringBuffer body = new StringBuffer();
if (bodyNames != null) {
while (bodyNames.hasMoreElements()) {
String name = bodyNames.nextElement();
String values = request.getParameter(name);
body.append(name).append("=").append(values).append("&");
}
}
if (body.length() != 0) {
body.deleteCharAt(body.length() - 1);
template.body(body.toString());
}
}
}
上面代碼完成了對(duì)/add接口的攔截,通過自動(dòng)授權(quán),完成對(duì)授權(quán)接口kcUserClient.addUser();調(diào)用。
KcUserClient內(nèi)容
@FeignClient(name = "keycloak", url = "http://192.168.4.26:8080/auth", configuration = KcUserClient.Configuration.class)
public interface KcUserClient {
@PostMapping("/admin/realms/demo/users")
ResponseEntity<?> addUser(@RequestBody UserDTO userDTO);
@RequestMapping(value = "/realms/demo/protocol/openid-connect/token",
method = RequestMethod.POST,
consumes = "application/x-www-form-urlencoded")
KeycloakAccessToken login(@RequestBody AuthTokenRequest authTokenRequest);
/**
* 轉(zhuǎn)向器.
*/
class Configuration {
@Bean
Encoder feignFormEncoder(ObjectFactory<HttpMessageConverters> converters) {
return new SpringFormEncoder(new SpringEncoder(converters));
}
}
}
浙公網(wǎng)安備 33010602011771號(hào)