I receive a status 401 error: Unauthorized when i attempt to call my Secured API by keycloak
I receive a status 401 error: Unauthorized when i attempt to call my Secured API by keycloak
我向你揭露我的问题。
我有一个调用 REST API 的 Web 应用程序来查找客户的购物车。
应用程序和 API 受到 spring 安全和 SSO Keycloak 的保护。
实际上,我的 webapp 可以正常工作,如果我不保护我的 api,一切就绪。
但是当我想用角色保护我的 api 时,我每次都会遇到错误 401 错误:未经授权。事实上很好,我的 api 是安全的,但是具有角色 "USER" 的客户无法访问他的购物车。
当我尝试将我的不记名令牌带到 keycloak 时,是一个很好的令牌(在 jwt.io 中过去)。我尝试使用 curl,但结果是一样的。
我在我的网络应用程序中使用 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
我的方法在controller中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;
}
谢谢你的帮助。
我注意到,您在安全配置中混合了 hasAuthority
和 hasRole
方法。应该是 hasAuthority("ROLE_USER")
或 hasRole("USER")
。您检查过 "/commandes/**"
资源是否适合您吗?
好的,经过一些研究,我找到了问题的原因。
首先,Zuul 获得我请求的授权 header...
为了解决这个问题,我在我的属性 "zuul.sensitiveHeaders: Cookie, Set-Cookie" 中添加了这一行(所以,Zuul 只是保护 Cookie 和 Set-Cookie)。
接下来,在我的代码中,我发送了好的令牌,但我需要在我的令牌字符串之前精确 "Bearer "。
也许该解决方案可以帮助某人 :)
我向你揭露我的问题。 我有一个调用 REST API 的 Web 应用程序来查找客户的购物车。 应用程序和 API 受到 spring 安全和 SSO Keycloak 的保护。
实际上,我的 webapp 可以正常工作,如果我不保护我的 api,一切就绪。
但是当我想用角色保护我的 api 时,我每次都会遇到错误 401 错误:未经授权。事实上很好,我的 api 是安全的,但是具有角色 "USER" 的客户无法访问他的购物车。
当我尝试将我的不记名令牌带到 keycloak 时,是一个很好的令牌(在 jwt.io 中过去)。我尝试使用 curl,但结果是一样的。
我在我的网络应用程序中使用 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
.propertieskeycloak.auth-server-url=http://myserver:port/auth
keycloak.realm=wild_adventures
keycloak.resource=ms-commande
keycloak.credentials.secret=#######-####-####-####-###########
keycloak.bearer-only=true
我的方法在controller中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;
}
谢谢你的帮助。
我注意到,您在安全配置中混合了 hasAuthority
和 hasRole
方法。应该是 hasAuthority("ROLE_USER")
或 hasRole("USER")
。您检查过 "/commandes/**"
资源是否适合您吗?
好的,经过一些研究,我找到了问题的原因。
首先,Zuul 获得我请求的授权 header... 为了解决这个问题,我在我的属性 "zuul.sensitiveHeaders: Cookie, Set-Cookie" 中添加了这一行(所以,Zuul 只是保护 Cookie 和 Set-Cookie)。
接下来,在我的代码中,我发送了好的令牌,但我需要在我的令牌字符串之前精确 "Bearer "。
也许该解决方案可以帮助某人 :)