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 {
@Bean
public RequestInterceptor getOAuth2RequestInterceptor() throws IOException {
return new OAuth2FeignRequestInterceptor();
}
}
进入发现OAuth2FeignRequestInterceptor源码
public OAuth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext, OAuth2ProtectedResourceDetails resource) {
this(oAuth2ClientContext, resource, "Bearer", "Authorization");
}
参数OAuth2ClientContext,OAuth2ProtectedResourceDetails
OAuth2ClientContext是一个接口,有实现类DefaultOAuth2ClientContext,会有一个默认DefaultAccessTokenRequest请求类,加入拦截器参数
@Bean
public 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/token
token-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: 10000
web-client-configuration:
#keep in sync with UAA configuration
client-id: web_app
secret: changeit
修改配置bean OAuth2Properties
private final ClientAuthorization clientAuthorization =