定时器(@Scheduled)使用feign夸服务调用,Oauth2 客户端client_credentials模式
定时器(@Scheduled)使用feign夸服务调用,Oauth2 客户端client_credentials模式
应用场景
定时器(@Scheduled)使用feign夸服务调用(A——>B)。因为不是web请求,所以没有HTTP 请求信息,所以:ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); 获取不到token。报null值异常。
(PS:我的A服务是专门做定时器的服务,不走任何web请求!)
解决办法(仅代表个人)
我在A服务调用B服务之前加了一个私有的feign拦截器(写在了A服务里面):使用Oauth2的客户端(client_credentials)模式获取到token并塞进了请求头中。
参数说明
/oauth/token 是Oauth2 提供的token获取地址
grant_type=client_credentials 代表客户端模式请求token
client_id=schedule “schedule”数据库设置的
client_secret=123456 “123456 ”数据库设置的
scope 代表权限,不填代表所有
package cn.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.util.Map;/*** 实现RequestInterceptor接口:* feign全局设置求头信息*/
@Configuration
public class MyFeignRequestInterceptor implements RequestInterceptor {@ResourceRestTemplate restTemplate;@Overridepublic void apply(RequestTemplate requestTemplate) {Map<String,Object> objectMap = restTemplate.getForObject("http://jhcloud-portal/oauth/token?grant_type=client_credentials&client_id=schedule&client_secret=123456",Map.class);String token = objectMap.get("access_token").toString();requestTemplate.header("Authorization", "bearer "+token);}
}
然后在全局的feignConfig中加个判断
package cn.jhcloud_common.config;
@Configuration
public class FeignConfig implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if (attributes == null) {//因为私有的feign拦截器,所以请求头里已经有了token信息了,就不需要在这里在做处理了!}else {HttpServletRequest request = attributes.getRequest();requestTemplate.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION));}//seata分布式事务requestTemplate.header(RootContext.KEY_XID, RootContext.getXID());}
}
使用 RestTemplate调用的时候最好设置一个全局的:RestTemplateConfig,不然可能会报错。
package cn.jhcloud_common.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig {@Bean@LoadBalanced //让这个RestTemplate在请求时拥有客户端负载均衡的能力public RestTemplate getRestTemplate() {return new RestTemplate();}}
yml 里面最好也设置一下,如果不设置的话。会报:I/O ERROR ON GET REQUEST FOR "http://jhcloud-portal/auth/currentUser":
security:oauth2:resource:#每次调用接口都获取一下当前登录人的信息user-info-uri: http://jhcloud-portal/auth/currentUser loadBalanced: true #让这个RestTemplate在请求时拥有客户端负载均衡的能力
- [ 1、] 可能存在的问题,因为yml里面设置了每次调用接口之前都需要先获取一下当前登录人的信息,然而客户端模式获取到的token,不是用户token,所以没有用户信息,相应的也没有用户权限。所以postmain可能会"无效的token"错误。根据控制台报错信息定位一下会发现是:FixedAuthoritiesExtractor.extractAuthorities 报错
所以你可能需要在获取用户信息的地方,“/currentUser”。自己封装一下权限
然后正常调用就可以了。
因为时间有点长,遇到的其他问题也忘了。先写这么多吧。想起来再补充.
定时器(@Scheduled)使用feign夸服务调用,Oauth2 客户端client_credentials模式相关推荐
- Feign实现服务调用
上一篇博客我们使用ribbon+restTemplate实现负载均衡调用服务,接下来我们使用feign实现服务的调用,首先feign和ribbon的区别是什么呢? ribbon根据特定算法,从服务列表 ...
- Spring Cloud —— Feign 实现服务调用
引言 本篇博客简单介绍 Feign 的基础知识和基本应用,以前一篇博客<Spring Cloud Alibaba--Nacos实现服务治理>为代码基础,实现更简单的微服务调用方式. 一.什 ...
- feign调用多个服务_SpringCloud使用Feign实现服务调用|chu
Spring Cloud Feign简介 Spring Cloud Feign也是一个基础工具类,它整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两 ...
- 文件上传结合SpringCloud的Feign进行服务调用
工作中一直使用的是SpringCloud,其中的多个组件的使用也已经有一段时间了,包括对组件的配置文件的编写,今天要讲的是SpringCloud中的一个远程服务调用的组件,使用Feign之后,我们调用 ...
- SpringCloud中Feign进行服务调用 java.io.IOException: too many bytes written 问题解决
问题描述 Spring Cloud 中通过 Feign 调用微服务时,报错:java.io.IOException: too many bytes written 问题来源 在 Feign 调用拦截器 ...
- [Spring cloud 一步步实现广告系统] 11. 使用Feign实现微服务调用
上一节我们使用了Ribbon(基于Http/Tcp)进行微服务的调用,Ribbon的调用比较简单,通过Ribbon组件对请求的服务进行拦截,通过Eureka Server 获取到服务实例的IP:Por ...
- feign响应拦截_[Spring cloud 一步步实现广告系统] 11. 使用Feign实现微服务调用
上一节我们使用了Ribbon(基于Http/Tcp)进行微服务的调用,Ribbon的调用比较简单,通过Ribbon组件对请求的服务进行拦截,通过Eureka Server 获取到服务实例的IP:Por ...
- 微服务feignclient_[Spring cloud 一步步实现广告系统] 11. 使用Feign实现微服务调用
上一节我们使用了Ribbon(基于Http/Tcp)进行微服务的调用,Ribbon的调用比较简单,通过Ribbon组件对请求的服务进行拦截,通过Eureka Server 获取到服务实例的IP:Por ...
- Spring Cloud之(十一)服务调用Feign
十一.服务调用Feign 11.1 Feign简介 Feign是Netflix开发的声明式,模板化的HTTP客户端,其灵感来自Retrofit,JAXRS-2.0以及WebSocket. Feign可 ...
最新文章
- 云原生安全的挑战与实践
- 除了数据,生活中还有这些......
- VTK:Medical之MedicalDemo3
- Idea单测执行报错“Command line is too long“ 解决办法
- vue项目路径修改及打包上传到服务器
- MindSpore手写数字识别初体验,深度学习也没那么神秘嘛
- win10运行DOSBox配置Debug
- [150529](必看)档案挂靠与打回生源地、暂缓的对比 (广州)
- springboot no tests were found
- Win32串口API
- 如何用python做比分网_python爬虫足球比分-yltg888
- 怎么做好宝贝标题优化?
- 固定Java窗口的大小
- 微信支付服务商加密字段解析。
- 通向实在之路暂记003:双曲几何
- 生物信息分析:从入门到精通结语
- 【微信小程序】冒泡事件与非冒泡事件、将文章数据从业务中分离、wxml的模块化
- h5在微信中打开长按保存图片
- 刚毕业入职一个多月就被裁,赔偿半个月工资两万四!
- JavaScript学习笔记(二十七)——服务器