问题出现条件:
使用现在最新版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
问题:
- feign接口如何访问oauth2保护的资源服务器
- hystrix不传播安全性或者说Hystrix shareSecurityContext不工作
解决:
- feign接口如何访问oauth2保护的资源服务器
1、编写文件属性类
package com.yp.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Created by CrazyMouse on 2017/7/20.
*/
@ConfigurationProperties(prefix = "security.oauth2.client")
public class OAuth2Properties {
private String clientId;
private String clientSecret;
private String accessTokenUri;
private String userAuthorizationUri;
private String clientAuthenticationScheme;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getAccessTokenUri() {
return accessTokenUri;
}
public void setAccessTokenUri(String accessTokenUri) {
this.accessTokenUri = accessTokenUri;
}
public String getUserAuthorizationUri() {
return userAuthorizationUri;
}
public void setUserAuthorizationUri(String userAuthorizationUri) {
this.userAuthorizationUri = userAuthorizationUri;
}
public String getClientAuthenticationScheme() {
return clientAuthenticationScheme;
}
public void setClientAuthenticationScheme(String clientAuthenticationScheme) {
this.clientAuthenticationScheme = clientAuthenticationScheme;
}
}
2、编写OAuth2FeignResourceDetails类
package com.yp.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.common.AuthenticationScheme;
import java.util.List;
/**
* Created by CrazyMouse on 2017/7/20.
*/
@EnableConfigurationProperties(OAuth2Properties.class)
public class OAuth2FeignResourceDetails implements OAuth2ProtectedResourceDetails {
@Autowired
private OAuth2Properties properties;
@Override
public String getId() {
return null;
}
@Override
public String getClientId() {
return null;
}
@Override
public String getAccessTokenUri() {
return properties.getAccessTokenUri();
}
@Override
public boolean isScoped() {
return false;
}
@Override
public List<String> getScope() {
return null;
}
@Override
public boolean isAuthenticationRequired() {
return false;
}
@Override
public String getClientSecret() {
return properties.getClientSecret();
}
@Override
public AuthenticationScheme getClientAuthenticationScheme() {
return AuthenticationScheme.valueOf(properties.getClientAuthenticationScheme());
}
@Override
public String getGrantType() {
return null;
}
@Override
public AuthenticationScheme getAuthenticationScheme() {
return null;
}
@Override
public String getTokenName() {
return null;
}
@Override
public boolean isClientOnly() {
return false;
}
}
3、编写OAuth2FeignConguration类
package com.yp.demo.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import java.util.Optional;
/**
* Created by CrazyMouse on 2017/7/20.
*/
@Configuration
public class OAuth2FeignConguration {
@Bean("oAuth2ClientContext")
public OAuth2ClientContext oAuth2ClientContext() {
return new DefaultOAuth2ClientContext() {
@Override
public OAuth2AccessToken getAccessToken() {
return Optional.ofNullable(super.getAccessToken())
.orElse(new DefaultOAuth2AccessToken(
((OAuth2AuthenticationDetails) SecurityContextHolder
.getContext().getAuthentication().getDetails())
.getTokenValue()));
}
};
}
@Bean
public OAuth2FeignRequestInterceptor requestInterceptor(@Qualifier("oAuth2ClientContext") OAuth2ClientContext oAuth2ClientContext) {
return new OAuth2FeignRequestInterceptor(oAuth2ClientContext, new OAuth2FeignResourceDetails());
}
}
4、配置feign接口
package com.yp.demo.feign;
import com.yp.demo.config.OAuth2FeignConguration;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.HashMap;
/**
* Created by CrazyMouse on 2017/7/20.
*/
@FeignClient(name = "microservice-resource",
configuration = {OAuth2FeignConguration.class}, fallbackFactory = UserFeign.UserFeignFallbackFactory.class)
public interface UserFeign {
@RequestMapping(value = "/user", method = RequestMethod.GET)
Object getUser();
@Component
class UserFeignFallbackFactory implements FallbackFactory<UserFeign> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserFeignFallbackFactory.class);
@Override
public UserFeign create(Throwable throwable) {
return () -> {
LOGGER.info("fallback reason was: ", throwable);
HashMap<String, Object> json = new HashMap<>();
json.put("code", 0);
json.put("message", "资源服务器宕机");
return json;
};
}
}
}
- hystrix不传播安全性或者说Hystrix shareSecurityContext不工作
1、在application.yml中加入
hystrix:
shareSecurityContext: true
2、在上面的OAuth2FeignConguration中已经配置了,就是下面的代码
@Bean("oAuth2ClientContext")
public OAuth2ClientContext oAuth2ClientContext() {
return new DefaultOAuth2ClientContext() {
@Override
public OAuth2AccessToken getAccessToken() {
return Optional.ofNullable(super.getAccessToken())
.orElse(new DefaultOAuth2AccessToken(
((OAuth2AuthenticationDetails) SecurityContextHolder
.getContext().getAuthentication().getDetails())
.getTokenValue()));
}
};
}
可以参考下面资料
https://github.com/spring-cloud/spring-cloud-netflix/issues/1330
https://github.com/spring-cloud/spring-cloud-netflix/issues/1336
demo项目地址
https://git.oschina.net/dream-maker/spring-cloud-sso-plus
网友评论