zuul:不接受承载认证

Posted

技术标签:

【中文标题】zuul:不接受承载认证【英文标题】:zuul : Bearer authentication not accepted 【发布时间】:2016-11-11 02:27:18 【问题描述】:

我有一个应用程序试图在 Zuul 代理下调用 RESTApi。

应用程序具有由 OAuth2 服务器提供的有效 jwt 令牌。 我在标头中的不记名授权中有令牌,但我有来自 zuul 服务器的 401(“访问此资源需要完全身份验证”)响应。

我的zuul配置:

eureka:
    client:
        registerWithEureka: true
        fetchRegistry: true
        serviceUrl:
            defaultZone: http://localhost:8761/eureka/
    instance:
        leaseRenewalIntervalInSeconds: 10
        statusPageUrlPath: $management.context_path/info
        healthCheckUrlPath: $management.context_path/health

server:
    port: 80
management:
    port: 81
    context_path: /admin

security:
    sessions: stateless
      # Disable Spring Boot basic authentication
    basic:
        enabled: false

endpoints:
    restart:
        enabled: true
    shutdown:
        enabled: true
    health:
        sensitive: false

# The OAuth2 server definition that would be used to send the authorization requests to
authserver:
    hostname: localhost
    port: 9000
    contextPath: uaa

spring:
    oauth2:
        resource:
            userInfoUri: http://$authserver.hostname:$authserver.port/$authserver.contextPath/user
            jwt.key-uri: http://$authserver.hostname:$authserver.port/$authserver.contextPath/oauth/token_key
            preferTokenInfo: false

    output:
        ansi:
            enabled: ALWAYS

主要的zuul文件:

@SpringBootApplication
@EnableZuulProxy
@EnableResourceServer
public class ZuulApplication 

    public static void main(String[] args) 
        new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
    

zuul安全配置文件:

@Configuration
public class WebSecurityConfiguration extends ResourceServerConfigurerAdapter  

    @Override
    public void configure(HttpSecurity http) throws Exception 
        http
                .csrf().disable()
                .exceptionHandling()
                .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                    .antMatchers("/admin/trace").permitAll()
                    .anyRequest().authenticated()
                ;
    


restApi的调用:

        final String access_token = (String) httpSession.getAttribute(OAuthComponent.HTTPSESSION_OAUTH_ACCESS_TOKEN);

        final MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Authorization", "Bearer " + access_token);
        headers.add("Content-Type", "application/json");

        final HttpEntity<Object> request = new HttpEntity<>(searchParams,headers);

        return restOperations.postForObject("http://localhost/ms-arbre-recherche/utilisateur/search", request, Object.class);

我使用 spring cloud Brixton SR2 和 spring boot 1.4.0RC1。

【问题讨论】:

你有什么关于 git 的例子可以看看吗? 抱歉,没有 git 示例。 【参考方案1】:

这是我的安全配置:

@Configuration
@EnableResourceServer
public class JwtSecurityConfig extends ResourceServerConfigurerAdapter

    @Override
    public void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests()
            .antMatchers("/oauth/**").permitAll()
            .antMatchers("/**").hasAuthority("ROLE_API")
            .and()
            .csrf().disable();
    

我所做的主要不同之处在于我使用的是 OauthRestTemplate。

@Configuration
public class ActivationApiEndpointConfig 

    @Bean
    protected OAuth2ProtectedResourceDetails resource() 

        ClientCredentialsResourceDetails  resource = new ClientCredentialsResourceDetails();



    resource

 .setAccessTokenUri("http://cdpsit04is01.eng.rr.com:8888/oauth/token");

        resource.setClientId("clientid");
        resource.setClientSecret("clientsecret");
        resource.setGrantType("client_credentials");
        resource.setScope(Arrays.asList("write", "read"));
        resource.setAuthenticationScheme(AuthenticationScheme.header);

        return resource;
    

    @Bean
    public OAuth2RestOperations applicationApiTemplate() 
        AccessTokenRequest atr = new DefaultAccessTokenRequest();

        return new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
    


然后

String returnValue = applicationApiTemplate.getForObject(uri.expand(pathVariables).toUri(), String.class);

你还需要确保你的 pom 中有这个(或依赖):

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-jwt</artifactId>
</dependency>

【讨论】:

以上是关于zuul:不接受承载认证的主要内容,如果未能解决你的问题,请参考以下文章

spring security oauth2认证中心 集成zuul网关的代码分析

SpringCloudAlibaba+Zuul+OAuth2 搭建认证微服务

Yii2 Rest API 承载认证

SailsJS v1.0 承载认证(API 令牌)

Spring Cloud:微服务认证通过 Eureka Discovery 工作,而不是通过 Zuul

支持 JWT 密钥轮换的承载令牌认证的 Owin 中间件