Запрос почтальона не выполняется в защищенном API REST с помощью Keycloak | Весенняя безопасность

Здравствуйте, я новичок в keycloak и Spring Security. У меня есть REST API серверной службы. Я пытаюсь защитить его с помощью keycloak. Проблема в том, что когда я делаю запрос POST с помощью Postman, он возвращает ответ 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.

Вот мой java-файл Spring SecurityConfig.

@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

Так выглядит мой запрос токена OAuth2 в Postman

Запрос токена OAuth2 почтальона

Настройки клиента

введите здесь описание изображения

введите здесь описание изображения

Для учетных данных задан идентификатор клиента, а секретные роли имеют роль администратора. введите здесь описание изображения

введите здесь описание изображения

Конфигурации почтальона

Конфигурации Keycloak почтальона


person Menuka Ishan    schedule 23.01.2019    source источник


Ответы (3)


Если у кого-то еще есть эта проблема, вам нужно создать роль под клиентом (клиенты - ›{ваш клиент} -› роли- ›добавить роль), а не в области.

Затем назначьте пользователю роль клиента.

пример: назначение роли пользователя

это мой токен:

{...
,
  "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"
      ]
    }
  },
...
}

Журнал загрузки Spring:

Завершение аутентификации на предъявителя. Роли на предъявителя: [пользователь]

Надеюсь, кому-то это пригодится. :)

person Anthon    schedule 09.07.2020
comment
Что-то пошло не так во время моих тестов с клиентом. Я переименовал и произвольно щелкал по ролевым меню. Мне пришлось создать клиента с нуля, и это работало с ролями клиентов. Используйте clients->your-client->scopes->evaluate->generated access token, чтобы убедиться, что у вас есть роли ресурсов внутри токена. - person simno; 16.07.2021

Я предлагаю вам протестировать свою конечную точку с помощью запроса GET (вместо POST, PUT, PATCH или любого другого небезопасного глагола). Если это работает, то ваш 403 не связан с keycloak или вашим токеном доступа, но связан с проверкой csrf (подделка межсайтовых запросов), которая активируется Spring Security как поведение по умолчанию для всех небезопасных глаголов.

Несколько недель назад у меня была аналогичная проблема, проверьте ее здесь: путем защиты и конечной точки с ролью, работает с ботами методов GET, а не с POST, я получаю 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 = ложь

person tony _008    schedule 11.10.2019

Похоже, ваш токен-носитель не содержит никакой роли, а вашей службе нужна роль «admin», поэтому вы получаете 403. Назначены ли роли вашему пользователю, получившему токен?

person Sébastien Blanc    schedule 24.01.2019
comment
Вы можете объяснить, как добавить эту роль? Потому что у моего пользователя роль администратора. Я не знаю, как добавлять роли к ролям - person Menuka Ishan; 24.01.2019
comment
Его нужно просто добавить к вашему токену доступа без каких-либо действий, это роль области? Не могли бы вы также сказать мне, какую версию Keycloak вы используете? - person Sébastien Blanc; 24.01.2019
comment
Я использую Keycloak 4.7.0.Final Я знаю о роли пользователя в клиенте, но не о ролях Bear. Поэтому я обновил вопрос с деталями, которые, как мне казалось, были бы полезны. Пожалуйста помоги :) - person Menuka Ishan; 24.01.2019
comment
Не могли бы вы также поделиться конфигурацией вашего клиента? - person Sébastien Blanc; 24.01.2019
comment
Вероятно, это id_token, а не настоящий access_token. К сожалению, в вашем вопросе нет информации об использованном response_type. - person Jan Garaj; 25.01.2019
comment
@ SébastienBlanc Я обновил вопрос, указав сведения о клиенте. Пожалуйста помоги - person Menuka Ishan; 25.01.2019
comment
@JanGaraj Где я могу найти response_type подробности? : O - person Menuka Ishan; 25.01.2019
comment
Это должно быть в вашем запросе почтальона. Но из вопроса неясно, какой поток и запрос вы используете для получения токена. - person Jan Garaj; 25.01.2019
comment
@JanGaraj Я обновил вопрос с конфигурациями почтальона. Вы можете проверить это, пожалуйста? - person Menuka Ishan; 25.01.2019
comment
Вы используете тип предоставления учетных данных клиента. Попробуйте использовать тип предоставления кода авторизации. - person Jan Garaj; 26.01.2019
comment
Я попробовал. Он открывает веб-страницу Почтальон, я могу использовать неправильный URL-адрес аутентификации. Я взял его из stackoverflow.com/a/28673597/2940265 Мой URL-адрес аутентификации выглядит как localhost: 8180 / auth / realms / MyDemo / tokens / login это неправильный URL для почтальона? - person Menuka Ishan; 28.01.2019