美文网首页Java服务器端编程程序员IT技术篇
来自另一个线程的feign + hystrix + oauth2

来自另一个线程的feign + hystrix + oauth2

作者: 就怕是个demo | 来源:发表于2017-07-20 14:23 被阅读1051次

    问题出现条件:
    使用现在最新版本

    <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

    相关文章

      网友评论

        本文标题:来自另一个线程的feign + hystrix + oauth2

        本文链接:https://www.haomeiwen.com/subject/qugdkxtx.html