springcloud中feign调用的权限认证

我们之前做了一个consumer调用producer的接口,用的是feign,现在我们将OAuth2与Jwt加入了认证服务,此时使用feign是失败的,因为在请求到达consumer服务时,token被解析,调用feign时是一个新请求,此时请求是不带token的,在producer服务端会失败.
在feign调用时,我们是可以在请求发出时将token添加进去,

这里有两种选择:

1.调用feign时将原本请求的token拿过来给feign使用
2.我们可以从客户端模式获取token,放入feign中
我这里是第二种方式::
我们定义myuaa客户端模式时,是将客户端模式加入了的,只需我们将客户端模式token加入,不论是谁,这个feign调用都可行,在spring中有一个请求拦截器RequestInterceptor,有一个security的实现OAuth2FeignRequestInterceptor,我们需要定义这个拦截器
定义一个feign配置类,方便管理区分其他的配置类
FeignConfiguration

@Configuration
public class FeignConfiguration {@Beanpublic RequestInterceptor getOAuth2RequestInterceptor() throws IOException {return new OAuth2FeignRequestInterceptor();}
}

进入发现OAuth2FeignRequestInterceptor源码

 public OAuth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext, OAuth2ProtectedResourceDetails resource) {this(oAuth2ClientContext, resource, "Bearer", "Authorization");}

参数OAuth2ClientContext,OAuth2ProtectedResourceDetails
OAuth2ClientContext是一个接口,有实现类DefaultOAuth2ClientContext,会有一个默认DefaultAccessTokenRequest请求类,加入拦截器参数

 @Beanpublic RequestInterceptor getOAuth2RequestInterceptor() throws IOException {return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(),);}

OAuth2ProtectedResourceDetails也是一个接口,实现类比较多,我们是准备用客户端模式,所以必填参数有grant_type与oauth/token的url,选择BaseOAuth2ProtectedResourceDetails的子类ClientCredentialsResourceDetails,这里需要注意一下,
整个流程说白了,就是创建一个RequestInterceptor,再重写的apply方法中对请求添加含有token的head
首先在OAuth2Properties中添加配置:

oauth2:client-authorization:access-token-uri: http://myuaa/oauth/tokentoken-service-id: myuaa    //认证服务名signature-verification:public-key-endpoint-uri: http://myuaa/oauth/token_key#ttl for public keys to verify JWT tokens (in ms)ttl: 3600000#max. rate at which public keys will be fetched (in ms)public-key-refresh-rate-limit: 10000web-client-configuration:#keep in sync with UAA configurationclient-id: web_appsecret: changeit

修改配置bean OAuth2Properties

private final ClientAuthorization clientAuthorization = new ClientAuthorization();
public ClientAuthorization getClientAuthorization() {return clientAuthorization;}public static class ClientAuthorization {private String accessTokenUri;private String tokenServiceId ;public String getAccessTokenUri() {return accessTokenUri;}public void setAccessTokenUri(String accessTokenUri) {this.accessTokenUri = accessTokenUri;}public String getTokenServiceId() {return tokenServiceId;}public void setTokenServiceId(String tokenServiceId) {this.tokenServiceId = tokenServiceId;}}

在FeignConfiguration中注入

@Configuration
public class FeignConfiguration {@AutowiredOAuth2Properties oAuth2Properties;@AutowiredLoadBalancerClient loadBalancerClient;public String getURL() {  //获取token完整路径if (oAuth2Properties.getClientAuthorization().getTokenServiceId().isEmpty()) {try {return loadBalancerClient.reconstructURI(loadBalancerClient.choose(oAuth2Properties.getClientAuthorization().getTokenServiceId()),new URI(oAuth2Properties.getClientAuthorization().getAccessTokenUri())).toString();} catch (URISyntaxException e) {e.printStackTrace();}}return oAuth2Properties.getClientAuthorization().getAccessTokenUri();}

做一个ClientCredentialsResourceDetails的bean

 @Beanpublic ClientCredentialsResourceDetails loadClientCredentialsResourceDetails() {ClientCredentialsResourceDetails clientCredentialsResourceDetails = new ClientCredentialsResourceDetails();clientCredentialsResourceDetails.setAccessTokenUri(getURL());clientCredentialsResourceDetails.setClientId(oAuth2Properties.getWebClientConfiguration().getClientId());clientCredentialsResourceDetails.setClientSecret(oAuth2Properties.getWebClientConfiguration().getSecret());return clientCredentialsResourceDetails;}
 @Beanpublic RequestInterceptor getOAuth2RequestInterceptor() throws IOException {return new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(),loadClientCredentialsResourceDetails());}

这里就完成了,

源码讲解

由于我的是用的OAuth2FeignRequestInterceptor拦截器,他里面实现了apply方法

 public void apply(RequestTemplate template) {template.header(this.header, new String[]{this.extract(this.tokenType)});}protected String extract(String tokenType) {OAuth2AccessToken accessToken = this.getToken();return String.format("%s %s", tokenType, accessToken.getValue());}

在这里是不能用OAuth2ProtectedResourceDetails的实现类BaseOAuth2ProtectedResourceDetails,因为源码中获取token时会对Resource进行种类判断,必须为五种grant_type对应的类,

         Iterator var3 = this.chain.iterator();AccessTokenProvider tokenProvider;do {if (!var3.hasNext()) {throw new OAuth2AccessDeniedException("Unable to obtain a new access token for resource '" + details.getId() + "'. The provider manager is not configured to support it.", details);}tokenProvider = (AccessTokenProvider)var3.next();} while(!tokenProvider.supportsResource(details));

2.也可以直接使用自定义类来实现RequestInterceptor,自己写

public class FeignOAuthRequestInterceptor implements RequestInterceptor {@Autowiredprivate  OAuth2RestTemplate oAuth2RestTemplate;@Overridepublic void apply(RequestTemplate requestTemplate) {requestTemplate.header("Authorization",String.format("%s %s","Bearer",oAuth2RestTemplate.getAccessToken().toString()));}}

注入OAuth2RestTemplate,对他来一个实例化bean

@Configuration
public class Oauth2ClientConfig {@AutowiredOAuth2Properties oAuth2Properties;@AutowiredLoadBalancerClient loadBalancerClient;public String getAccessTokenUri() {if (!oAuth2Properties.getClientAuthorization().getTokenServiceId().isEmpty())try {String string = loadBalancerClient.reconstructURI(loadBalancerClient.choose(oAuth2Properties.getClientAuthorization().getTokenServiceId()),new URI(oAuth2Properties.getClientAuthorization().getAccessTokenUri())).toString();return string;} catch (URISyntaxException e) {e.printStackTrace();}return null;}@Beanpublic ClientCredentialsResourceDetails resourceDetails() {ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();details.setAccessTokenUri(getAccessTokenUri());details.setClientId(oAuth2Properties.getWebClientConfiguration().getClientId());details.setClientSecret(oAuth2Properties.getWebClientConfiguration().getSecret());return details;}@Beanpublic OAuth2RestTemplate oAuth2RestTemplate() {final OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resourceDetails(), new DefaultOAuth2ClientContext());oAuth2RestTemplate.setRequestFactory(new SimpleClientHttpRequestFactory());//Netty4ClientHttpRequestFactory());//SimpleClientHttpRequestFactoryreturn oAuth2RestTemplate;}@Beanpublic RequestInterceptor oauth2FeignRequestInterceptor(@Qualifier("paascloudOAuth2RestTemplate") OAuth2RestTemplate oAuth2RestTemplate) {return new FeignOAuthRequestInterceptor();}
}

springcloud中feign调用的权限认证相关推荐

  1. SpringCloud 中 Feign 调用添加 Oauth2 Authorization Header

    SpringCloud 中 Feign 调用添加 Oauth2 Authorization Header SpringCloud 中通过 Feign 调用其他服务,当服务使用 Oauth2 授权的时候 ...

  2. 解决SpringBoot+SpringCloud中feign调用服务传递参数为MultipartFile的问题

    文章目录 前言 一.前期说明 二.使用步骤 1.引入maven依赖 2.新建feign的配置类 2.feign客户端 3.被调用的服务的Controller 4.第三方服务远程调用主服务传递Multi ...

  3. SpringCloud 中 Feign 核心原理,简单易懂!

    目录 SpringCloud 中 Feign 核心原理 Feign远程调用的基本流程 Feign 远程调用的重要组件 Feigh 远程调用的执行流程 SpringCloud 中 Feign 核心原理 ...

  4. SpringCloud 中Feign原理(图解)

    1 SpringCloud 中Feign原理 1.1 Feign简介 Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端.Spring Clou ...

  5. SpringCloud中Feign进行服务调用 java.io.IOException: too many bytes written 问题解决

    问题描述 Spring Cloud 中通过 Feign 调用微服务时,报错:java.io.IOException: too many bytes written 问题来源 在 Feign 调用拦截器 ...

  6. SpringCloud中Feign服务调用请求方式及参数总结

    前言 最近做微服务架构的项目,在用feign来进行服务间的调用.在互调的过程中,难免出现问题,根据错误总结了一下,主要是请求方式的错误和接参数的错误造成的.在此进行一下总结记录.以下通过分为三种情况说 ...

  7. SpringCloud中Feign的适配器的实现方案

    前言 最近在做微服务的项目,各个系统之间需要进行调用,然后用一个适配器来实现服务之间的feign调用,使用适配器进行统一管理. 实现方案 首先我们需要将服务的名称进行单独的配置,可以方便的进行切换和扩 ...

  8. Shiro中进行角色与权限认证流程

    场景 使用Shiro的JdbcRealm实现查询数据库进行身份认证: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/9010599 ...

  9. SpringCloud中 Feign结合Hystrix断路器开发。

    Feign结合Hystrix断路器开发: 转载于:https://www.cnblogs.com/longdb/p/10468371.html

  10. SpringCloud 各个微服务之间会话共享以及Feign调用会话共享

    目录 1.会话共享应用背景 2.SpringCloud各个微服务 (SpringBoot)应用之间会话共享 2.1.启动类或者Redis配置类加入Redis会话共享注解 2.2.配置Redis基本配置 ...

最新文章

  1. 嵌入式linux应用程序升级,基于嵌入式Linux平台的应用升级机制的研究与设计
  2. python使用matplotlib可视化、自定义移除Y轴指定轴刻度标签(removing specific axis ticks in matplotlib y axis)
  3. 王洪超:WPF催熟整个软件生态链
  4. “人工智能大脑”跳槽记:吴恩达所理解的智能
  5. 苏宁大数据怎么运营_运营商大数据精准获客
  6. [转]Android 代码混淆和加固 so库 简单教你一行代码实现
  7. 从概念到案例:初学者须知的十大机器学习算法
  8. js正则验证方法大全
  9. cls_template.php on line 1072,博客 – 联发多彩网页技术博客
  10. 为Python终端提供持久性历史记录
  11. mysql5.1 主主同步_mysql主主同步指定库的指定表(version 5.1~5.7)
  12. C#随机不重复给数组赋值1-100并排序
  13. 关于模型转向自然化思考
  14. Android计算器简单实现及代码分析
  15. PMP备考经验分享 制表很重要
  16. 《视觉SLAM十四讲》笔记摘抄
  17. Shapley值法介绍及实例计算
  18. Excel-每隔几行进行转置一次
  19. 星期一到星期日的英文 缩写 读音 巧记方法
  20. Jetson Nano开发深度学习实践(六) :工作站(主机)装机-NVIDIA显卡驱动,Cuda,Cudnn

热门文章

  1. Win10与苹果AirDrop(隔空投送)
  2. 高手攻关考试心得:RHCE实战详细经验
  3. 唯美的英文短文!!!
  4. python自动化plc_PYTHON – 让“Monty 语言”进入自动化行业:第 4 部分
  5. mc服务器图标修改,高版本配置文件修改(添加,修改交易)
  6. Ceph 知识摘录(Ceph对象存储网关中的索引工作原理)
  7. 【Numpy】1. n维数组,dtype,切片,索引
  8. mqdf python_GitHub - jugg1024/court_recognition
  9. SpringBoot项目遇到AopAutoConfiguration matched: - @ConditionalOnProperty (spring.aop.auto=true)错误
  10. 2021年安全员-C证考试题库及安全员-C证考试资料