我收到状态 401 错误:当我尝试通过 keycloak 调用我的 Secured API 时未授权

Posted

技术标签:

【中文标题】我收到状态 401 错误:当我尝试通过 keycloak 调用我的 Secured API 时未授权【英文标题】:I receive a status 401 error: Unauthorized when i attempt to call my Secured API by keycloak 【发布时间】:2019-05-25 22:52:54 【问题描述】:

我向您揭露我的问题。 我有一个调用 REST API 来查找客户端购物车的 web 应用程序。 应用程序和 API 由 spring security 和 SSO Keycloak 保护。

其实我的webapp是正常的,如果我不保护我的api,一切都准备好了。

但是当我想用角色保护我的 api 时,我每次都会遇到错误 401 错误:未授权。事实上很好,我的 api 是安全的,但是具有“USER”角色的客户无法访问他的购物车。

当我尝试将我的不记名令牌带到 keycloak 时,这是一个很好的令牌(过去在 jwt.io 中)。我尝试使用 curl,但结果是一样的。

我在我的 webapp 中使用 Feign 来调用 API。

我的 api 中的 Keycloak 配置

@Configuration
@EnableWebSecurity
@ConditionalOnProperty(name = "keycloak.enabled", havingValue = "true", matchIfMissing = true)
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public static class KeycloakConfigurationAdapter extends KeycloakWebSecurityConfigurerAdapter

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() 
        return new NullAuthenticatedSessionStrategy();
    

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    

    @Bean
    public KeycloakConfigResolver KeycloakConfigResolver()
        return new KeycloakSpringBootConfigResolver();
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http
                .csrf().disable()
                .sessionManagement()
                    .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                .and()
                    .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
                    .addFilterBefore(keycloakAuthenticationProcessingFilter(), X509AuthenticationFilter.class)
                    .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())

                .and()
                    .authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
                    .antMatchers("/paniers/**").hasAuthority("USER")
                    .antMatchers("/commandes/**").hasRole("USER")
                    .anyRequest().permitAll();
    

我的 API .properties

keycloak.auth-server-url=http://myserver:port/auth
keycloak.realm=wild_adventures
keycloak.resource=ms-commande
keycloak.credentials.secret=#######-####-####-####-###########
keycloak.bearer-only=true

我在api控制器中的方法

@ApiOperation(value = "Récupère le panier avec la liste des évenements réservés ou renvoie un 404 NotFound")
@GetMapping(value = "paniers/clientUuid")
public Panier recupererPanier(@PathVariable(value = "clientUuid") String clientUuid) 

    Panier panier = this.panierManager.getPanierByClientUuid(clientUuid);

    if(panier == null)
        throw new PanierInexistantException("Le panier n'a pas été trouvé");

    return panier;

感谢您的帮助。

【问题讨论】:

【参考方案1】:

好的,经过一番研究,我找到了问题的原因。

首先,Zuul 保护了我的请求的 Authorization 标头... 为了解决这个问题,我在我的属性“zuul.sensitiveHeaders: Cookie, Set-Cookie”中添加了这一行(所以,Zuul 只是保护 Cookie 和 Set-Cookie)。

接下来,在我的代码中,我发送了好的令牌,但我需要在我的令牌字符串之前精确地输入“Bearer”。

也许该解决方案可以帮助某人:)

【讨论】:

您应该能够接受自己的答案。这会将这个问题标记为已回答。【参考方案2】:

我注意到,您在安全配置中混合了 hasAuthorityhasRole 方法。应该是hasAuthority("ROLE_USER")hasRole("USER")。您是否检查过"/commandes/**" 资源是否适合您?

【讨论】:

抱歉,hasAutority 只是一个测试,但主要是 hasRole。我用 curl 测试了«/commandes/**»,我遇到了同样的错误。

以上是关于我收到状态 401 错误:当我尝试通过 keycloak 调用我的 Secured API 时未授权的主要内容,如果未能解决你的问题,请参考以下文章

MailChimp 错误状态:401 标题:“API 密钥无效”

当我使用 asmx 服务和 s-s-rS 报告服务时,我收到“请求失败,http 状态 401:未授权”

使用 httr get 时出现错误 401

当我发送超过过期日期的令牌时,为啥会收到 401 错误?

JHipster:测试微服务时收到 401 Unauthorized

我收到 Uncaught (in promise) 错误:请求失败,状态码为 401