Spring Boot & Keycloak - работает только для метода get
Следующее работает нормально:
@GetMapping(path = "/onlyforAdmins")
@Secured("ROLE_ADMIN")
public ResponseEntity<?> secureHello(Principal principal) {
return new ResponseEntity<String>("hello " + principal.getName(), HttpStatus.OK);
}
Тем не менее, я всегда получаю 403, когда я пытаюсь сделать следующее:
@RequestMapping(path = "/setupCase", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method=RequestMethod.POST)
@Secured("ROLE_ADMIN")
public MyCase setupCase(@RequestParam(required = false) String loggedInUser) throws Exception {
Когда я переключаю метод на method=RequestMethod.GET
все работает нормально.
У меня есть следующая конфигурация:
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.AuthorizedUrl;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@ConditionalOnClass(
name = {"org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter"}
)
@ConditionalOnProperty(
value = {"keycloak.enabled"},
matchIfMissing = true
)
@EnableWebSecurity
@EnableGlobalMethodSecurity(
securedEnabled = true
)
@ComponentScan(
basePackageClasses = {KeycloakSecurityComponents.class}
)
public class MockWebSecurityConfigurerAdapter extends KeycloakWebSecurityConfigurerAdapter {
public MockWebSecurityConfigurerAdapter() {
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = this.keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
((AuthorizedUrl)((AuthorizedUrl)((AuthorizedUrl)((AuthorizedUrl)http.authorizeRequests().antMatchers(new String[]{"/togglz-console/*"})).hasRole("ADMIN").antMatchers(new String[]{"/swagger-ui.html"})).hasRole("ADMIN").antMatchers(new String[]{"/admin/*"})).hasRole("ADMIN").anyRequest()).permitAll();
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
И следующие зависимости:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>4.1.0.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Так как же сделать так, чтобы метод post обрабатывался так же, как метод get? И избегайте постоянных 403, хотя я вошел в систему с ролью администратора.
Обновить
Я включил ведение журнала и вижу следующее:
o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8092/setupCase
1 ответ
Проблема была связана со стандартной защитой CSRF пружины.
Для отправки запросов необходимо предоставить токен CSRF.
Добавление следующего временно к конфигурации, заставило 403 уйти:
http.csrf().disable();
Столкнулся с той же проблемой. Решением для нас было также включить csrf(). Disable(), но внутри метода переопределения KeycloakConfiguration.java configure().
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable()
.authorizeRequests()
.antMatchers(NO_AUTH_PATHS).permitAll()
.anyRequest().authenticated();
}