在Keycloak受保护的REST API中,邮递员请求失败春季安全

时间:2019-01-23 10:59:51

标签: rest spring-security keycloak keycloak-services

你好,我是keycloak和Spring Security的新手。 我有一个后端服务REST API。我正在尝试使用密钥斗篷保护它。问题是当我使用Postman发出POST请求时,它返回403 Forbidden响应。我检查了Keycloak中的日志,它们似乎可以通过keycloak进行身份验证。我隔离了一个POST API请求的日志。有人可以说我的配置出了什么问题吗?

2019-01-23 16:17:14 DEBUG - adminRequest http://localhost:8080/api/users
2019-01-23 16:17:14 DEBUG - AuthenticatedActionsValve.invoke /api/users
2019-01-23 16:17:14 DEBUG - AuthenticatedActionsValve.invoke http://localhost:8080/api/users
2019-01-23 16:17:14 DEBUG - Policy enforcement is disabled.
2019-01-23 16:17:14 DEBUG - adminRequest http://localhost:8080/api/users
2019-01-23 16:17:14 DEBUG - Request is to process authentication
2019-01-23 16:17:14 DEBUG - Attempting Keycloak authentication
2019-01-23 16:17:14 TRACE - --> authenticate()
2019-01-23 16:17:14 TRACE - try bearer
2019-01-23 16:17:14 DEBUG - Verifying access_token
2019-01-23 16:17:14 TRACE -     access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJBeThhY0RDeURhM0NKWVhjeUVPQkhEWkpIS2U4TTV3T3JpeU1UTmZLWngwIn0.eyJqdGkiOiI5NzFkNDg4YS1iMGJkLTRiMTUtOTgzNC1lYzIxN2NlYzAxZDMiLCJleHAiOjE1NDgyNDA3MzAsIm5iZiI6MCwiaWF0IjoxNTQ4MjQwNDMwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvTXlEZW1vIiwic3ViIjoiMWZiNTlmMjItYTMzMi00YjdmLWJkMzgtYzE5M2RiYTI0ZDk5IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXktcmVhY3QtY2xpZW50IiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiYmRiNzA4N2ItNGViMi00NzMyLWIzNGQtY2RmYTEwZjgxNjA0IiwiYWNyIjoiMSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJNZW51a2EgSXNoYW4iLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbi11c2VyIiwiZ2l2ZW5fbmFtZSI6Ik1lbnVrYSIsImZhbWlseV9uYW1lIjoiSXNoYW4iLCJlbWFpbCI6Im1lbnVrYUBoc2VuaWQubGsifQ.signature
2019-01-23 16:17:14 DEBUG - successful authorized
2019-01-23 16:17:14 TRACE - checking whether to refresh.
2019-01-23 16:17:14 TRACE - useResourceRoleMappings
2019-01-23 16:17:14 TRACE - Setting roles: 
2019-01-23 16:17:14 DEBUG - Completing bearer authentication. Bearer roles: [] 
2019-01-23 16:17:14 DEBUG - User '1fb59f22-a332-4b7f-bd38-c193dba24d99' invoking 'http://localhost:8080/api/users' on client 'my-react-client'
2019-01-23 16:17:14 DEBUG - Bearer AUTHENTICATED
2019-01-23 16:17:14 DEBUG - Auth outcome: AUTHENTICATED
2019-01-23 16:17:14 DEBUG - Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@dacf45b2: Principal: 1fb59f22-a332-4b7f-bd38-c193dba24d99; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@6bb92c4a; Not granted any authorities
2019-01-23 16:17:14 DEBUG - AuthenticatedActionsValve.invoke http://localhost:8080/api/users
2019-01-23 16:17:14 DEBUG - Policy enforcement is disabled.
2019-01-23 16:17:14 DEBUG - adminRequest http://localhost:8080/error
2019-01-23 16:17:14 DEBUG - Request is to process authentication
2019-01-23 16:17:14 DEBUG - Attempting Keycloak authentication
2019-01-23 16:17:14 TRACE - --> authenticate()
2019-01-23 16:17:14 TRACE - try bearer
2019-01-23 16:17:14 DEBUG - Verifying access_token
2019-01-23 16:17:14 TRACE -     access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJBeThhY0RDeURhM0NKWVhjeUVPQkhEWkpIS2U4TTV3T3JpeU1UTmZLWngwIn0.eyJqdGkiOiI5NzFkNDg4YS1iMGJkLTRiMTUtOTgzNC1lYzIxN2NlYzAxZDMiLCJleHAiOjE1NDgyNDA3MzAsIm5iZiI6MCwiaWF0IjoxNTQ4MjQwNDMwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvTXlEZW1vIiwic3ViIjoiMWZiNTlmMjItYTMzMi00YjdmLWJkMzgtYzE5M2RiYTI0ZDk5IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibXktcmVhY3QtY2xpZW50IiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiYmRiNzA4N2ItNGViMi00NzMyLWIzNGQtY2RmYTEwZjgxNjA0IiwiYWNyIjoiMSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJNZW51a2EgSXNoYW4iLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbi11c2VyIiwiZ2l2ZW5fbmFtZSI6Ik1lbnVrYSIsImZhbWlseV9uYW1lIjoiSXNoYW4iLCJlbWFpbCI6Im1lbnVrYUBoc2VuaWQubGsifQ.signature
2019-01-23 16:17:14 DEBUG - successful authorized
2019-01-23 16:17:14 TRACE - checking whether to refresh.
2019-01-23 16:17:14 TRACE - useResourceRoleMappings
2019-01-23 16:17:14 TRACE - Setting roles: 
2019-01-23 16:17:14 DEBUG - Completing bearer authentication. Bearer roles: [] 
2019-01-23 16:17:14 DEBUG - User '1fb59f22-a332-4b7f-bd38-c193dba24d99' invoking 'http://localhost:8080/error' on client 'my-react-client'
2019-01-23 16:17:14 DEBUG - Bearer AUTHENTICATED
2019-01-23 16:17:14 DEBUG - Auth outcome: AUTHENTICATED
2019-01-23 16:17:14 DEBUG - Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@93251b1b: Principal: 1fb59f22-a332-4b7f-bd38-c193dba24d99; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@13c4eea7; Not granted any authorities
2019-01-23 16:17:14 DEBUG - AuthenticatedActionsValve.invoke http://localhost:8080/error
2019-01-23 16:17:14 DEBUG - Policy enforcement is disabled.

这是我的Spring SecurityConfig java文件。

@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {


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

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }


    @Bean
    public KeycloakConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
//    FilterRegistrationBean to avoid Bean duplicate registrations
    @Bean
    public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
            KeycloakAuthenticationProcessingFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
            KeycloakPreAuthActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
            KeycloakAuthenticatedActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(
            KeycloakSecurityContextRequestFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);

        http.authorizeRequests()
                .antMatchers("/api/**").hasRole("admin")
                .anyRequest().authenticated();

        http.csrf().disable();

    }
}

这是我用户的角色。

Keycloak user

这是我在邮递员中的OAuth2令牌请求的样子

Postman OAuth2 token request

客户端设置

enter image description here

enter image description here

凭据设置为“客户端ID”和“秘密角色”具有管理员角色。 enter image description here

enter image description here

邮递员配置

Postman Keycloak configurations

3 个答案:

答案 0 :(得分:1)

我建议您使用 GET请求(而不是POST,PUT,PATCH或任何其他不安全的动词)来测试端点。如果这可行,则您的403与密钥斗篷或访问令牌无关,但与csrf(跨站点请求伪造)有关,请检查是否将spring安全性激活为所有非安全动词的默认行为。

几周前,我遇到了类似的问题,请在此处进行检查: by securing and endpoint with a role, works for GET methods bot not POST, I receive 403 Forbiden。如果确实是问题所在,那么那里还会提供解决方案。

注意:如果您的GET端点获得相同的403,则问题与令牌中不存在该角色有关。在此页面中: https://jwt.io/,您有一个访问令牌解码工具,可以帮助您可视化令牌及其所有声明的内容,因此很容易检查所需角色是否不存在。

希望有帮助!

编辑: 实际上,您是在配置中禁用csrf:

http.csrf().disable();

因此,这似乎与csrf检查无关。使用上面的工具查看令牌的内容,并验证其是否包含保护该端点的角色。即使您的角色存在,也请检查您是否在“ realm_access”或“ resource_access”下。如果您将其放在“ resource_access”下,则需要将以下行添加到应用程序属性中:

  

keycloak.use-resource-role-mappings = true

如果您在“ realm_access”下具有该角色,则可以删除上面的行,或将其设置为false:

  

keycloak.use-resource-role-mappings = false

答案 1 :(得分:1)

如果其他人仍然遇到此问题,则需要在“客户端”(客户端-> {您的客户端}->角色->添加角色)下而不是在“领域”下创建角色。

然后将客户端角色分配给用户。

示例: user role assignment

这是我的令牌内容:

{...
,
  "realm_access": {
    "roles": [
      "offline_access",
      "uma_authorization",
      "user" // not visible in spring security
    ]
  },
  "resource_access": {
    "backstage-api": {
      "roles": [
        "user" // visible in spring security
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
...
}

春季启动日志:

“正在完成承载身份验证。承载角色:[用户]”

我希望有人觉得这有用。 :)

答案 2 :(得分:0)

看起来您的承载令牌不包含任何角色,您的服务需要角色“ admin”,这就是为什么您获得403的原因。获得令牌的用户是否分配了角色?