Keycloak 说 403 Forbidden for HTTP 方法而不是 GET
Posted
技术标签:
【中文标题】Keycloak 说 403 Forbidden for HTTP 方法而不是 GET【英文标题】:Keycloak says 403 Forbidden for HTTP Methods other than GET 【发布时间】:2019-08-22 14:22:51 【问题描述】:我正在设置一个 Keycloak 实例以与包含 Spring Security 的 Spring Boot 应用程序一起使用。我使用邮递员来测试服务。我从获取新的访问令牌开始,效果很好。当我对安全端点进行 HTTP GET 调用时 - 一切正常,人员返回。但是当我对安全端点进行 HTTP POST/PUT/DELETE 调用时,Keycloak 显示错误 403 Forbidden。请看一下并告诉我出了什么问题。
我已经测试了 http.csrf().disable() 选项,然后工作正常,但这不是生产的解决方案。
SecurityConfig.java
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver()
return new KeycloakSpringBootConfigResolver();
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy()
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
@Override
protected void configure(HttpSecurity http) throws Exception
super.configure(http);
http
.authorizeRequests()
.antMatchers( "/api/**").hasRole("my_admin")
.anyRequest().permitAll();
application.yml:
keycloak:
auth-server-url: http://localhost:11080/auth
realm: myrealm
resource: myclient
public-client: true
principal-attribute: preferred_username
ssl-required: external
use-resource-role-mappings: true
来自应用程序的一些日志(keycloak 跟踪日志级别):
2019-04-01 14:04:54.741 DEBUG 2952 --- [io-1080-exec-10] o.k.adapters.PreAuthActionsHandler : adminRequest http://localhost:1080/api/my-endpoint
2019-04-01 14:04:54.741 DEBUG 2952 --- [io-1080-exec-10] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /api/my-endpoint
2019-04-01 14:04:54.741 DEBUG 2952 --- [io-1080-exec-10] o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke http://localhost:1080/api/my-endpoint
2019-04-01 14:04:54.741 DEBUG 2952 --- [io-1080-exec-10] o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
2019-04-01 14:04:54.742 DEBUG 2952 --- [io-1080-exec-10] o.k.adapters.PreAuthActionsHandler : adminRequest http://localhost:1080/error
2019-04-01 14:04:54.743 DEBUG 2952 --- [io-1080-exec-10] f.KeycloakAuthenticationProcessingFilter : Request is to process authentication
2019-04-01 14:04:54.743 DEBUG 2952 --- [io-1080-exec-10] f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
2019-04-01 14:04:54.743 TRACE 2952 --- [io-1080-exec-10] o.k.adapters.RequestAuthenticator : --> authenticate()
2019-04-01 14:04:54.743 TRACE 2952 --- [io-1080-exec-10] o.k.adapters.RequestAuthenticator : try bearer
2019-04-01 14:04:54.743 DEBUG 2952 --- [io-1080-exec-10] o.k.a.BearerTokenRequestAuthenticator : Found [1] values in authorization header, selecting the first value for Bearer.
2019-04-01 14:04:54.743 DEBUG 2952 --- [io-1080-exec-10] o.k.a.BearerTokenRequestAuthenticator : Verifying access_token
2019-04-01 14:04:54.743 TRACE 2952 --- [io-1080-exec-10] o.k.a.BearerTokenRequestAuthenticator : access_token: eyJhbs...blablab....signature
2019-04-01 14:04:54.744 DEBUG 2952 --- [io-1080-exec-10] o.k.a.BearerTokenRequestAuthenticator : successful authorized
2019-04-01 14:04:54.744 TRACE 2952 --- [io-1080-exec-10] o.k.a.RefreshableKeycloakSecurityContext : checking whether to refresh.
2019-04-01 14:04:54.744 TRACE 2952 --- [io-1080-exec-10] org.keycloak.adapters.AdapterUtils : useResourceRoleMappings
2019-04-01 14:04:54.744 TRACE 2952 --- [io-1080-exec-10] org.keycloak.adapters.AdapterUtils : Setting roles:
2019-04-01 14:04:54.744 TRACE 2952 --- [io-1080-exec-10] org.keycloak.adapters.AdapterUtils : role: my_admin
2019-04-01 14:04:54.744 DEBUG 2952 --- [io-1080-exec-10] a.s.a.SpringSecurityRequestAuthenticator : Completing bearer authentication. Bearer roles: [my_admin]
2019-04-01 14:04:54.745 DEBUG 2952 --- [io-1080-exec-10] o.k.adapters.RequestAuthenticator : User 'my_user' invoking 'http://localhost:1080/error' on client 'myclient'
2019-04-01 14:04:54.745 DEBUG 2952 --- [io-1080-exec-10] o.k.adapters.RequestAuthenticator : Bearer AUTHENTICATED
2019-04-01 14:04:54.745 DEBUG 2952 --- [io-1080-exec-10] f.KeycloakAuthenticationProcessingFilter : Auth outcome: AUTHENTICATED
2019-04-01 14:04:54.745 DEBUG 2952 --- [io-1080-exec-10] f.KeycloakAuthenticationProcessingFilter : Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@fb0506b7: Principal: my_user; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@ecf147d; Granted Authorities: ROLE_my_admin
2019-04-01 14:04:54.745 DEBUG 2952 --- [io-1080-exec-10] o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke http://localhost:1080/error
2019-04-01 14:04:54.745 DEBUG 2952 --- [io-1080-exec-10] o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
【问题讨论】:
如果您设置了 CSRF 保护,您还需要您的客户端发送 CSRF 令牌。如果你不是从邮递员那里做的,它会失败。 【参考方案1】:你应该做以下两个配置:
-
在 spring 配置中禁用 csrf
http.csrf().disable()
在 client 而不是 realm 中定义角色,并为用户分配客户端级别的角色
【讨论】:
我只需要禁用 CSRF 就可以解决这个问题,但是禁用 CSRF 可以吗?【参考方案2】:我发现我没有在 ajax 请求中使用 CSRF 令牌。 Spring Security 自动启用 CSRF 保护。 CSRF 令牌是为首次调用 Web 服务自动生成的,它具有会话范围。您需要将该令牌保存在元标记中。每个非 GET 请求都需要包含 CSRF 令牌(GET 请求不需要使用 CSRF 令牌保护,因为它们旨在用于非修改 API 调用)。
解决方案:只需在 html 页面 (thymeleaf) 的标题中包含该行:<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<meta id="_csrf" name="_csrf" th:content="$_csrf.token"/>
并在标头中的 ajax 调用中使用它:headers:
'X-CSRF-TOKEN': $('#_csrf').attr('content')
,
【讨论】:
【参考方案3】:是 Spring Security 提供的 CSRF 保护。您真的需要使用 Keycloak 令牌进行这种保护吗?令牌仅包含在 cookie 中还是也存在于 Authorization 标头中?
【讨论】:
身份令牌存储在cookies中,访问令牌在header中传递 如果访问令牌在标头中传递,则不需要 CSRF 令牌。看来您正在使用带有 spring security 和 keycloak 适配器的 Spring boot:不要忘记禁用 keycloak 适配器提供的 4 个过滤器,因为它们是由 Spring boot 自动注册的。以上是关于Keycloak 说 403 Forbidden for HTTP 方法而不是 GET的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot - KeyCloak 指向 403 禁止
403 spring-boot-2-keycloak-适配器
boto elastic beanstalk CreateApplicationVersion 403 Forbidden