#spring-boot #post #spring-security #keycloak #put
#spring-boot #Публикация #spring-безопасность #keycloak #поместить
Вопрос:
Я настраиваю экземпляр Keycloak для работы с приложением spring boot с включенной защитой spring. Я использую postman для тестирования сервиса. Я начинаю с получения нового токена доступа, и это работает нормально. Когда я выполняю HTTP GET-вызов защищенной конечной точки — все идет нормально, персонал возвращается. Но когда я выполняю HTTP-вызов POST / PUT / DELETE для защищенной конечной точки, Keycloak сообщает, что ошибка 403 запрещена. Пожалуйста, взгляните и скажите мне, что пошло не так.
Я уже протестировал опцию 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.
Комментарии:
1. Если вы настроили защиту CSRF, вам нужно, чтобы ваш клиент также отправлял токен CSRF. Если вы не выполняете это из postman, произойдет сбой.
Ответ №1:
вы должны выполнить две следующие настройки:
- отключите csrf в spring config
http.csrf().disable()
- определите роль в клиенте вместо области и назначьте пользователю роль уровня клиента
Комментарии:
1. Мне пришлось отключить CSRF только для решения этой проблемы, но можно ли отключить CSRF?
Ответ №2:
Я обнаружил, что не использовал токен CSRF в запросах ajax. Spring Security автоматически включает защиту CSRF. Токен CSRF автоматически генерируется для первого вызова веб-службы и имеет область действия сеанса. Вам нужно сохранить этот токен в мета-теге. Требуется включать токен CSRF в каждый запрос, не связанный с GET (запросы 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:
Это защита CSRF, предоставляемая Spring Security. Вам действительно нужна эта защита с помощью токена Keycloak? Токен включен только в файл cookie или он также присутствует в заголовке авторизации?
Комментарии:
1. Идентификационный токен хранится в файлах cookie, токен доступа передается в заголовке
2. Если токен доступа передается в заголовке, вам не нужен токен CSRF. Похоже, вы используете Spring boot с spring security и адаптером keycloak: не забудьте отключить 4 фильтра, предоставляемых адаптером keycloak, поскольку они автоматически регистрируются Spring boot.
3. Что такое четыре фильтра?
4. Прошло более 3 лет. Вам нужно прочитать документ keycloak: keycloak.org/docs/latest/securing_apps / … об этом. Фильтрами являются: KeycloakAuthenticationProcessingFilter, KeycloakPreAuthActionsFilter, KeycloakAuthenticatedActionsFilter, KeycloakSecurityContextRequestFilter. Кажется, есть еще 2 фильтра, которые регистрируются дважды в версии. Вам нужно выяснить, поскольку я больше не использую Keycloak.