簡體   English   中英

Spring 安全配置:HTTP 403錯誤

[英]Spring Security configuration: HTTP 403 error

我正在嘗試按照 web 上的指南使用 Spring Security 來保護我的網站。

所以在我的服務器端我有以下課程。

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

我的 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) {
        
    }
}

讓我非常困惑的是服務器不響應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)

我已經在 inte.net 上搜索了好幾天。 仍然沒有頭緒。 請幫忙。 非常感謝

該問題可能是由於CSRF 保護造成的。 如果用戶不會在 Web 瀏覽器中使用您的應用程序, 那么禁用 CSRF 保護是安全的 否則,您應該確保在請求中包含 CSRF 令牌

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

該問題可能與 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 保護,同意最高評論。 然而,通過使用這種配置,該方法取消了彈簧安全性。

因此,您可以使用以下代碼:

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

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

檢查您通過“標頭”發送的令牌,並在您的數據庫中查詢相同的令牌是否存在該令牌。

注意:以上僅適用於您使用 Spring Boot 令牌身份驗證機制的情況。

我發布這個以防其他人在將來發現它有用。 我花了幾個小時尋找失敗的地方,最后我找到了解決方案,在 Postman 上對 http://localhost:8080/login/ 進行 POST 與對 http://localhost:8080/login 進行 POST 不同(在請求末尾使用“/”將返回 403 forbidden)

將我的服務升級到 Spring Boot 3 后,我遇到了這個問題。自動測試開始失敗,狀態為 403。 經過相當多的頭痛之后,我發現它是由從 URL 匹配中刪除尾部斜線引起的。 此處描述了更改。 因此,請檢查您是否撥打了正確的 URL。

錯誤的:

/api/foo/

正確的:

/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