it-source

스프링 보안 설정: HTTP 403 오류

criticalcode 2023. 3. 27. 21:17
반응형

스프링 보안 설정: HTTP 403 오류

웹의 가이드에 따라 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
//@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/DELETEmethod, 반면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)

나는 며칠 동안 인터넷을 검색했다.아직 감을 못 잡겠어요제발 도와주세요.정말 감사합니다.

문제는 CSRF의 보호로 인해 발생할 수 있습니다.사용자가 웹 브라우저에서 응용 프로그램을 사용하지 않을 경우 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를 디세블로 하는 것만으로 403의 수신을 정지할 수 있습니다.

'헤더'를 통해 전송하는 토큰을 확인하고 데이터베이스에서 해당 토큰의 존재 여부를 쿼리하십시오.

주의: 위의 내용은 Spring Boot 토큰 인증 메커니즘을 사용하는 경우에만 적용됩니다.

앞으로 다른 사람이 유용하다고 생각할까 봐 글을 올립니다.무엇이 실패했는지를 몇 시간 동안 찾아봤더니 결국 해결 방법을 찾았습니다.Postman에서 POST를 http://localhost:8080/login/은 POST를 http://localhost:8080/login으로 하는 것과 다릅니다(요구의 마지막에 "/"를 지정하면 403이 금지됩니다).

서비스를 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();

언급URL : https://stackoverflow.com/questions/19468209/spring-security-configuration-http-403-error

반응형