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

时间:2018-12-28 02:24:16

标签: java spring-boot spring-security keycloak

我向你暴露了我的问题。 我有一个Web应用程序,该应用程序调用REST API来查找客户端的购物车。 春季安全性和SSO Keycloak保护了应用程序和API。

实际上,我的Web应用程序可以正常运行,如果我不保护自己的api,那么一切都准备就绪。

但是,当我想保护自己的api角色时,每次都会出现错误401错误:未经授权。实际上很好,我的api是安全的,但是角色为“ USER”的客户端无法访问其购物车。

当我尝试将我的不记名令牌带到密钥斗篷时,是一个很好的令牌(粘贴在jwt.io中)。我尝试使用curl,但是结果是一样的。

我在Web应用程序中使用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;
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:-1)

确定研究后,我找到了造成问题的原因。

首先,Zuul确保我的请求的“授权”标头... 为了解决这个问题,我在属性“ zuul.sensitiveHeaders:Cookie,Set-Cookie”中添加了这一行(因此,Zuul仅保护Cookie和Set-Cookie)。

接下来,在我的代码中,我发送了正确的令牌,但是我需要在令牌字符串之前精确定位“ Bearer”。

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