代码之家  ›  专栏  ›  技术社区  ›  Menelaos

Spring Boot&KeyColt-仅适用于get方法

  •  1
  • Menelaos  · 技术社区  · 6 年前

    @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
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   Menelaos    6 年前

    问题与默认的弹簧CSRF保护有关。

    Post请求需要提供CSRF令牌。

    将以下内容临时添加到配置中,使403消失:

    http.csrf().disable();
    
        2
  •  2
  •   user1653042    6 年前

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      super.configure(http);
    
      http.csrf().disable()
            .authorizeRequests()
            .antMatchers(NO_AUTH_PATHS).permitAll()
            .anyRequest().authenticated();
    }