【问题标题】:spring security 403 error弹簧安全403错误
【发布时间】:2013-10-28 09:24:34
【问题描述】:

我正在尝试按照网络上的指南使用 Spring 安全性来保护我的网站。所以在我的服务器端,WebSecurityConfigurerAdapter 和控制器看起来像这样

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
implements ApplicationContextAware {

@Override
protected void registerAuthentication(AuthenticationManagerBuilde r authManagerBuilder) throws Exception {
authManagerBuilder.inMemoryAuthentication()
.withUser("user").password("password").roles("ADMI N");
}
}

@Controller
//@RequestMapping("/course")
public class CourseController implements ApplicationContextAware{

@RequestMapping(value="/course", method = RequestMethod.GET, produces="application/json")
public @ResponseBody List<Course> get(// The critirion used to find.
@RequestParam(value="what", required=true) String what,
@RequestParam(value="value", required=true) String value) {
//.....
}

@RequestMapping(value="/course", method = RequestMethod.POST, produces="application/json")
public List<Course> upload(@RequestBody Course[] cs) {
}
}

让我非常困惑的是服务器不响应 POST/DELETE 方法,而 GET 方法工作正常。顺便说一句,我在客户端使用 RestTemplate。例外情况是:

Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 403 Forbidden
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:574)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:530)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:487)
    at org.springframework.web.client.RestTemplate.delete(RestTemplate.java:385)
    at hello.Application.createRestTemplate(Application.java:149)
    at hello.Application.main(Application.java:99)

我已经在互联网上搜索了几天。还是没有头绪。请帮忙。非常感谢

【问题讨论】:

  • 正确吗?角色(“ADMI N”)。 'I' 和 'N' 之间有一个空格。

标签: spring spring-mvc spring-security


【解决方案1】:

问题可能是由CSRF protection 引起的。如果用户不会在 Web 浏览器中使用您的应用程序,then it is safe to disable CSRF 保护。否则你应该确保include the CSRF token in the request

disable CSRF protection,您可以使用以下内容:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig
    extends WebSecurityConfigurerAdapter implements ApplicationContextAware {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // ...
            .csrf().disable();
    }

    @Override
    protected void registerAuthentication(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("ADMIN");
    }
}

【讨论】:

  • 谢谢罗伯。这是csrf问题。是的,我不希望我的用户使用网络浏览器来使用我的应用程序。它在客户端运行良好。但是在服务器端我得到了这个: o.s.web.servlet.PageNotFound : Request method 'POST' not supported 奇怪。我应该忽略它吗?
  • 我认为 PageNotFound 是一个我要解决的单独问题。您可能需要发布另一个问题,提供有关此错误的更多信息。
  • 禁用csrf 安全配置确实解决了我的问题。我发现很难跟上 Spring 初学者带来的所有这些隐藏的自动功能。
【解决方案2】:

检查您通过“标头”发送的令牌,并在您的数据库中查询该令牌是否存在。

注意:以上仅适用于您使用 Spring Boot 令牌认证机制的情况。

【讨论】:

    【解决方案3】:

    该问题可能与 CSRF 或 CORS 安全保护有关。

    • 对于 CSRF:如果应用程序用户没有从浏览器中使用它,您可以禁用它。
    • 对于 CORS:您可以指定来源并允许 HTTP 方法。

    以下代码禁用 CSRF 并允许所有来源和 HTTP 方法。所以使用时要注意。

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter  implements WebMvcConfigurer {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
        }
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("*");
        }
    
    }
    

    【讨论】:

    • 在生产环境中禁用 csrf() 是否危险?
    • 不要禁用 csrf。这是一个巨大的安全风险。如果您不知道这一点,我强烈建议您在禁用它之前查找它是什么。
    【解决方案4】:

    我也找了好几天了!只需使用 http.csrf().disable() 在您的配置方法上禁用 CSRF;这就是我的 put 请求停止接收 403 所需要做的一切。

    【讨论】:

      【解决方案5】:
      http.httpBasic().disable();
      http.authorizeRequests().antMatchers("/signup").permitAll().antMatchers("/*")
           .fullyAuthenticated().and().formLogin()
           .and().csrf().disable();
      http.csrf().disable();
      

      【讨论】:

      • 不鼓励只回答代码
      • 请解释一下你的答案
      【解决方案6】:

      这个问题很可能是由于 CSRF 保护,同意上面的评论。然而,通过使用这种配置,该方法取消了弹簧安全性。

      所以你可以使用下面的代码:

      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
      
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
      
              auth
                      .inMemoryAuthentication()
                          .withUser("admin")
                              .password(encoder.encode("admin"))
                              .roles("ADMIN", "USER")
                      .and()
                          .withUser("user")
                              .password(encoder.encode("password"))
                              .roles("USER");
          }
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http
                      .authorizeRequests()
                      .anyRequest()
                      .authenticated()
                      .and()
                      .httpBasic();
      
              http.csrf().disable();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-25
        • 2012-03-01
        • 2023-01-03
        • 2018-09-08
        • 1970-01-01
        • 2020-06-25
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多