简体   繁体   English

Spring 安全配置:HTTP 403错误

[英]Spring Security configuration: HTTP 403 error

I'm trying to secure my website using Spring Security following the guides on the web.我正在尝试按照 web 上的指南使用 Spring Security 来保护我的网站。

So on my server side I have the following classes.所以在我的服务器端我有以下课程。

My WebSecurityConfigurerAdapter :我的WebSecurityConfigurerAdapter

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

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

My controller:我的 controller:

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

    @RequestMapping(value="/course", method = RequestMethod.GET, produces="application/json")
    public @ResponseBody List<Course> get(  // The criterion 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) {
        
    }
}

What confused me very much is the server does not respond to the POST / DELETE method, while the GET method works fine.让我非常困惑的是服务器不响应POST / DELETE方法,而GET方法工作正常。 BTW, I'm using RestTemplate on the client side.顺便说一句,我在客户端使用RestTemplate

Exceptions are:例外情况是:

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)

I've searched the inte.net for days.我已经在 inte.net 上搜索了好几天。 Still don't have a clue.仍然没有头绪。 Please help.请帮忙。 Thanks so much非常感谢

The issue is likely due to CSRF protection .该问题可能是由于CSRF 保护造成的。 If users will not be using your application in a web browser, then it is safe to disable CSRF protection.如果用户不会在 Web 浏览器中使用您的应用程序, 那么禁用 CSRF 保护是安全的 Otherwise you should ensure to include the CSRF token in the request .否则,您应该确保在请求中包含 CSRF 令牌

To disable CSRF protection you can use the following:禁用 CSRF 保护,您可以使用以下命令:

@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");
    }
}

The issue may be related to CSRF or CORS Security Protection.该问题可能与 CSRF 或 CORS 安全保护有关。

  • FOR CSRF: You can disable it if the application users did not use it from browsers.对于 CSRF:如果应用程序用户没有从浏览器中使用它,您可以禁用它。
  • For CORS: You can specify the origin and allow HTTP Methods.对于 CORS:您可以指定来源并允许 HTTP 方法。

The below code disable CSRF and allow all origins and HTTP methods.下面的代码禁用 CSRF 并允许所有来源和 HTTP 方法。 so be aware when using it.所以使用时要注意。

@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("*");
    }

}

The issue is likely due to CSRF protection, agree with the top comment.该问题可能是由于 CSRF 保护,同意最高评论。 Nevertheless, by using this configuration, the method cancells the spring security.然而,通过使用这种配置,该方法取消了弹簧安全性。

So you can use the following code:因此,您可以使用以下代码:

@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();
    }
}

I've been looking for days too!我也找了好几天! Simply disabling CSRF on your configure method with http.csrf().disable();只需使用 http.csrf().disable() 在您的配置方法上禁用 CSRF; is all that needed to be done for my put requests to stop receiving 403.我的 put 请求停止接收 403 所需要做的就是这些。

Check your token which you are sending through 'Header' and also query in your database for the same token whether that token exist or not.检查您通过“标头”发送的令牌,并在您的数据库中查询相同的令牌是否存在该令牌。

Note : The above is applicable only in case you are using Spring Boot token authentication mechanism.注意:以上仅适用于您使用 Spring Boot 令牌身份验证机制的情况。

I'm posting this in case someone else finds it useful in the future.我发布这个以防其他人在将来发现它有用。 I spent hours looking for what was failing and finally I find the solution, on Postman making a POST to http://localhost:8080/login/ is not the same as making a POST to http://localhost:8080/login (with "/" at the end of request it will return 403 forbidden)我花了几个小时寻找失败的地方,最后我找到了解决方案,在 Postman 上对 http://localhost:8080/login/ 进行 POST 与对 http://localhost:8080/login 进行 POST 不同(在请求末尾使用“/”将返回 403 forbidden)

I had this problem after upgrading my service to Spring Boot 3. Automatic tests started to fail with a 403 status.将我的服务升级到 Spring Boot 3 后,我遇到了这个问题。自动测试开始失败,状态为 403。 After quite a lot of headaches, I found out it is caused by removing trailing slash from URL matching.经过相当多的头痛之后,我发现它是由从 URL 匹配中删除尾部斜线引起的。 The change is described here. 此处描述了更改。 So check that you are calling the correct URL.因此,请检查您是否拨打了正确的 URL。

Wrong:错误的:

/api/foo/

Right:正确的:

/api/foo
http.httpBasic().disable();
http.authorizeRequests().antMatchers("/signup").permitAll().antMatchers("/*")
     .fullyAuthenticated().and().formLogin()
     .and().csrf().disable();
http.csrf().disable();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM