欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring cloud oauth2 feign 遇到的坑及解決

 更新時(shí)間:2022年03月07日 14:31:43   作者:liu_zhaoming  
這篇文章主要介紹了spring cloud oauth2 feign 遇到的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

spring cloud oauth2 feign 遇到的坑

關(guān)于oauth2相關(guān)的內(nèi)容這里不重復(fù)描述,在spring cloud中在管理內(nèi)部api時(shí)鑒權(quán)相信有很多人會(huì)有疑問(wèn),這里描述兩種比較low的用法,由于公司內(nèi)部使用的是阿里云edas這里僅僅是記錄一下,如果有更好的用法在請(qǐng)賜教,不喜勿噴!

客戶端模式

提供三方j(luò)ar包

這里需要抽一個(gè)jar包,需要用到feign的為服務(wù)端直接利用maven模式引入feign即可

<dependencies>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>
? ? ? ? ? ? <artifactId>spring-cloud-starter-feign</artifactId>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>com.netflix.feign</groupId>
? ? ? ? ? ? <artifactId>feign-okhttp</artifactId>
? ? ? ? ? ? <version>8.18.0</version>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>
? ? ? ? ? ? <artifactId>spring-cloud-starter-oauth2</artifactId>
? ? ? ? </dependency>
? ? </dependencies>

核心類

  • CustomHystrixConcurrencyStrategy.java
  • Oauth2ClientProperties.java
  • OAuth2FeignAutoConfiguration.java
  • OAuth2FeignRequestInterceptor.java
package com.paascloud.security.feign;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
?* The class Oauth 2 client properties.
?*
?* @author paascloud.net @gmail.com
?*/
@Data
@ConfigurationProperties(prefix = "paascloud.oauth2.client")
public class Oauth2ClientProperties {
? ? private String id;
? ? private String accessTokenUrl;
? ? private String clientId;
? ? private String clientSecret;
? ? private String clientAuthenticationScheme;
}
package com.paascloud.security.feign;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.springframework.stereotype.Component;
import java.util.concurrent.Callable;
/**
?* The class Custom hystrix concurrency strategy.
?*
?* @author paascloud.net @gmail.com
?*/
@Component
public class CustomHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
? ? /**
? ? ?* Instantiates a new Custom hystrix concurrency strategy.
? ? ?*/
? ? public CustomHystrixConcurrencyStrategy() {
? ? ? ? HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
? ? }
? ? /**
? ? ?* Wrap callable callable.
? ? ?*
? ? ?* @param <T> ? ? ?the type parameter
? ? ?* @param callable the callable
? ? ?*
? ? ?* @return the callable
? ? ?*/
? ? @Override
? ? public <T> Callable<T> wrapCallable(Callable<T> callable) {
? ? ? ? return new HystrixContextWrapper<T>(callable);
? ? }
? ? /**
? ? ?* The class Hystrix context wrapper.
? ? ?*
? ? ?* @param <V> the type parameter
? ? ?*
? ? ?* @author paascloud.net @gmail.com
? ? ?*/
? ? public static class HystrixContextWrapper<V> implements Callable<V> {
? ? ? ? private HystrixRequestContext hystrixRequestContext;
? ? ? ? private Callable<V> delegate;
? ? ? ? /**
? ? ? ? ?* Instantiates a new Hystrix context wrapper.
? ? ? ? ?*
? ? ? ? ?* @param delegate the delegate
? ? ? ? ?*/
? ? ? ? HystrixContextWrapper(Callable<V> delegate) {
? ? ? ? this.hystrixRequestContext = HystrixRequestContext.getContextForCurrentThread();
? ? ? ? ? ? this.delegate = delegate;
? ? ? ? }
? ? ? ? /**
? ? ? ? ?* Call v.
? ? ? ? ?*
? ? ? ? ?* @return the v
? ? ? ? ?*
? ? ? ? ?* @throws Exception the exception
? ? ? ? ?*/
? ? ? ? @Override
? ? ? ? public V call() throws Exception {
? ? ? ? ? ? HystrixRequestContext existingState = HystrixRequestContext.getContextForCurrentThread();
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? HystrixRequestContext.setContextOnCurrentThread(this.hystrixRequestContext);
? ? ? ? ? ? ? ? return this.delegate.call();
? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? HystrixRequestContext.setContextOnCurrentThread(existingState);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
package com.paascloud.security.feign;
import feign.Logger;
import feign.RequestInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.Netty4ClientHttpRequestFactory;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.common.AuthenticationScheme;
/**
?* The class O auth 2 feign auto configuration.
?*
?* @author paascloud.net @gmail.com
?*/
@Configuration
@EnableConfigurationProperties(Oauth2ClientProperties.class)
public class OAuth2FeignAutoConfiguration {
? ? private final Oauth2ClientProperties oauth2ClientProperties;
? ? /**
? ? ?* Instantiates a new O auth 2 feign auto configuration.
? ? ?*
? ? ?* @param oauth2ClientProperties the oauth 2 client properties
? ? ?*/
? ? @Autowired
? ? public OAuth2FeignAutoConfiguration(Oauth2ClientProperties oauth2ClientProperties) {
? ? ? ? this.oauth2ClientProperties = oauth2ClientProperties;
? ? }
? ? /**
? ? ?* Resource details client credentials resource details.
? ? ?*
? ? ?* @return the client credentials resource details
? ? ?*/
? ? @Bean("paascloudClientCredentialsResourceDetails")
? ? public ClientCredentialsResourceDetails resourceDetails() {
? ? ? ? ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
? ? ? ? details.setId(oauth2ClientProperties.getId());
? ? ? ? details.setAccessTokenUri(oauth2ClientProperties.getAccessTokenUrl());
? ? ? ? details.setClientId(oauth2ClientProperties.getClientId());
? ? ? ? details.setClientSecret(oauth2ClientProperties.getClientSecret());
? ? ? ? details.setAuthenticationScheme(AuthenticationScheme.valueOf(oauth2ClientProperties.getClientAuthenticationScheme()));
? ? ? ? return details;
? ? }
? ? /**
? ? ?* O auth 2 rest template o auth 2 rest template.
? ? ?*
? ? ?* @return the o auth 2 rest template
? ? ?*/
? ? @Bean("paascloudOAuth2RestTemplate")
? ? public OAuth2RestTemplate oAuth2RestTemplate() {
? ? ? ? final OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resourceDetails(), new DefaultOAuth2ClientContext());
? ? ? ? oAuth2RestTemplate.setRequestFactory(new Netty4ClientHttpRequestFactory());
? ? ? ? return oAuth2RestTemplate;
? ? }
? ? /**
? ? ?* Oauth 2 feign request interceptor request interceptor.
? ? ?*
? ? ?* @param oAuth2RestTemplate the o auth 2 rest template
? ? ?*
? ? ?* @return the request interceptor
? ? ?*/
? ? @Bean
? ? public RequestInterceptor oauth2FeignRequestInterceptor(@Qualifier("paascloudOAuth2RestTemplate") OAuth2RestTemplate oAuth2RestTemplate) {
? ? ? ? return new OAuth2FeignRequestInterceptor(oAuth2RestTemplate);
? ? }
? ? /**
? ? ?* Feign logger level logger . level.
? ? ?*
? ? ?* @return the logger . level
? ? ?*/
? ? @Bean
? ? Logger.Level feignLoggerLevel() {
? ? ? ? return Logger.Level.FULL;
? ? }
}
package com.paascloud.security.feign;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.util.Assert;
/**
?* The class O auth 2 feign request interceptor.
?*
?* @author paascloud.net @gmail.com
?*/
public class OAuth2FeignRequestInterceptor implements RequestInterceptor {
? ? private static final String AUTHORIZATION_HEADER = "Authorization";
? ? private static final String BEARER_TOKEN_TYPE = "bearer";
? ? private final OAuth2RestTemplate oAuth2RestTemplate;
? ? /**
? ? ?* Instantiates a new O auth 2 feign request interceptor.
? ? ?*
? ? ?* @param oAuth2RestTemplate the o auth 2 rest template
? ? ?*/
? ? OAuth2FeignRequestInterceptor(OAuth2RestTemplate oAuth2RestTemplate) {
? ? ? ? Assert.notNull(oAuth2RestTemplate, "Context can not be null");
? ? ? ? this.oAuth2RestTemplate = oAuth2RestTemplate;
? ? }
? ? /**
? ? ?* Apply.
? ? ?*
? ? ?* @param template the template
? ? ?*/
? ? @Override
? ? public void apply(RequestTemplate template) {
? ? ? ? template.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, ?oAuth2RestTemplate.getAccessToken().toString()));
? ? }
}

調(diào)用端配置

引入maven依賴

<dependency>
? ? ? ? ? ? <groupId>com.liuzm.paascloud.common</groupId>
? ? ? ? ? ? <artifactId>paascloud-security-feign</artifactId>
? ? ? ? ? ? <version>1.0-SNAPSHOT</version>
</dependency>

@FeignClient加入configuration屬性

/**
?* The interface Mdc product feign api.
?* @author paascloud.net@gmail.com
?*/
@FeignClient(value = "paascloud-provider-mdc", configuration = OAuth2FeignAutoConfiguration.class, fallback = MdcProductFeignHystrix.class)
public interface MdcProductFeignApi {
? ? /**
? ? ?* Update product stock by id int.
? ? ?*
? ? ?* @param productDto the product dto
? ? ?*
? ? ?* @return the int
? ? ?*/
? ? @RequestMapping(value = "/api/product/updateProductStockById", method = RequestMethod.POST)
? ? int updateProductStockById(@RequestBody ProductDto productDto);
}

認(rèn)證服務(wù)器配置

@Override
? ? public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
? ? ? ? clients.withClientDetails(restClientDetailsService);
? ? }
package com.paascloud.provider.security;
import com.paascloud.security.core.properties.OAuth2ClientProperties;
import com.paascloud.security.core.properties.SecurityProperties;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.config.annotation.builders.InMemoryClientDetailsServiceBuilder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
?* The class Rest client details service.
?*
?* @author paascloud.net @gmail.com
?*/
@Component("restClientDetailsService")
public class RestClientDetailsServiceImpl implements ClientDetailsService {
? ? private ClientDetailsService clientDetailsService;
? ? @Autowired
? ? private SecurityProperties securityProperties;
? ? /**
? ? ?* Init.
? ? ?*/
? ? @PostConstruct
? ? public void init() {
? ? ? ? InMemoryClientDetailsServiceBuilder builder = new InMemoryClientDetailsServiceBuilder();
? ? ? ? if (ArrayUtils.isNotEmpty(securityProperties.getOauth2().getClients())) {
? ? ? ? ? ? for (OAuth2ClientProperties client : securityProperties.getOauth2().getClients()) {
? ? ? ? ? ? ? ? builder.withClient(client.getClientId())
? ? ? ? ? ? ? ? ? ? ? ? .secret(client.getClientSecret())
? ? ? ? ? ? ? ? ? ? ? ? .authorizedGrantTypes("refresh_token", "password", "client_credentials")
? ? ? ? ? ? ? ? ? ? ? ? .accessTokenValiditySeconds(client.getAccessTokenValidateSeconds())
? ? ? ? ? ? ? ? ? ? ? ? .refreshTokenValiditySeconds(2592000)
? ? ? ? ? ? ? ? ? ? ? ? .scopes(client.getScope());
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? clientDetailsService = builder.build();
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? /**
? ? ?* Load client by client id client details.
? ? ?*
? ? ?* @param clientId the client id
? ? ?*
? ? ?* @return the client details
? ? ?*
? ? ?* @throws ClientRegistrationException the client registration exception
? ? ?*/
? ? @Override
? ? public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
? ? ? ? return ?clientDetailsService.loadClientByClientId(clientId);
? ? }
}

bootstrap.yml配置

security:
? ? oauth2:
? ? ? tokenStore: jwt
? ? ? clients[0]:
? ? ? ? clientId: paascloud-client-uac
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"
? ? ? clients[1]:
? ? ? ? clientId: paascloud-browser
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"
? ? ? clients[2]:
? ? ? ? clientId: paascloud-client-gateway
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"
? ? ? clients[3]:
? ? ? ? clientId: paascloud-client-zipkin
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"
? ? ? clients[4]:
? ? ? ? clientId: paascloud-client-mdc
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"
? ? ? clients[5]:
? ? ? ? clientId: paascloud-client-omc
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"
? ? ? clients[6]:
? ? ? ? clientId: paascloud-client-opc
? ? ? ? clientSecret: paascloudClientSecret
? ? ? ? accessTokenValidateSeconds: 7200
? ? ? ? scope: "*"

到此客戶端模式配置完成!

基于spring security

開(kāi)放權(quán)限,利用url規(guī)范來(lái)規(guī)劃客戶端的url不通過(guò)auth2鑒權(quán),這里唯一的區(qū)別是在feign攔截器里處理的邏輯改一下,代碼如下

@Autowired
private OAuth2ClientContext context;
@Override
? ? public void apply(RequestTemplate template) {
? ? ? ? if(context.getAccessToken() != null && context.getAccessToken().getValue() != null && OAuth2AccessToken.BEARER_TYPE.equalsIgnoreCase(context.getAccessToken().getTokenType()) ){
? ? ? ? ? ? template.header("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, context.getAccessToken().getValue()));
? ? ? ? }
? ? }

spring cloud微服務(wù)增加oauth2權(quán)限后 feign調(diào)用報(bào)null

在授權(quán)服務(wù)里,用戶通過(guò)用戶名密碼,或者手機(jī)和驗(yàn)證碼等方式登陸之后,在http頭里會(huì)有授權(quán)的標(biāo)識(shí),在客戶端調(diào)用時(shí),需要添加當(dāng)時(shí)有效的token才可以正常訪問(wèn)被授權(quán)的頁(yè)面。

Content-Type:application/json
Authorization:Bearer d79c064c-8675-4047-a119-fac692e447e8

而在業(yè)務(wù)層里,服務(wù)與服務(wù)之間使用feign來(lái)實(shí)現(xiàn)調(diào)用,而授權(quán)的代碼我們可以通過(guò)攔截器實(shí)現(xiàn),在feign請(qǐng)求之前,把當(dāng)前服務(wù)的token添加到目標(biāo)服務(wù)的請(qǐng)求頭就可以了

一般是這樣實(shí)現(xiàn)的

/**
?* 發(fā)送FeignClient設(shè)置Header信息.
?* http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/
?* Hystrix傳播ThreadLocal對(duì)象
?*/
@Component
public class TokenFeignClientInterceptor implements RequestInterceptor {
? /**
? ?* token放在請(qǐng)求頭.
? ?*
? ?* @param requestTemplate 請(qǐng)求參數(shù)
? ?*/
? @Override
? public void apply(RequestTemplate requestTemplate) {
? ? RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
? ? if (requestAttributes != null) {
? ? ? HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
? ? ? requestTemplate.header("Authorization", request.getHeader("Authorization"));
? ? }
? }
}

上面的攔截器代碼沒(méi)有什么問(wèn)題,也很好理解,但事實(shí)上,當(dāng)你的feign開(kāi)啟了hystrix功能,如果開(kāi)啟了,需要把hystrix的策略進(jìn)行修改,默認(rèn)是THREAD的,這個(gè)級(jí)別時(shí)ThreadLocal是空的,所以你的授權(quán)不能傳給feign的攔截器.

hystrix:?
?? ?command:?
?? ??? ?default:?
?? ??? ??? ?execution:?
?? ??? ??? ??? ?isolation:?
?? ??? ??? ??? ??? ?strategy: SEMAPHORE?

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論