Spring Security anonymous 403 대신 401
Java Config에서 제공되는 권한 요청과 함께 스프링 보안의 기본 동작에 문제가 있습니다.
http
....
.authorizeRequests()
.antMatchers("/api/test/secured/*").authenticated()
예를 들어 에 콜을 할 때/api/test/secured/user로그인하지 않은 경우(익명의 사용자가 있는 경우), 403 Forbidden을 반환합니다.익명의 사용자가 보안 보호를 원할 때 상태를 401 Unauthorized로 쉽게 변경할 수 있는 방법이 있습니까?authenticated()또는@PreAuthorize자원?
Spring Boot 2 클래스 Http401 현재AuthenticationEntryPoint가 삭제되었습니다(스프링 부트 문제 10725 참조).
Http401 대신AuthenticationEntryPoint는 HttpStatus와 함께 HttpStatusEntryPoint를 사용합니다.승인되지 않음:
http.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
spring security 4.x에서는 이미 그에 대한 클래스가 있습니다.
org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint
스프링 부트에는 1개도 포함되어 있습니다.
org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint
또한 개발자가 401 응답으로서 스펙 준거를 사용하도록 요구하는 두 가지 이점 모두 헤더의 WWW-Authenticate를 설정해야 합니다.예를 들어 401 응답은 다음과 같습니다.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
error="invalid_token",
error_description="The access token expired"
따라서 보안 설정에서는 클래스 전체를 정의하고 자동 접속할 수 있습니다.
예를 들어 스프링 부트 앱의 경우:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
public Http401AuthenticationEntryPoint securityException401EntryPoint(){
return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
}
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").anonymous()
.antMatchers("/").anonymous()
.antMatchers("/api/**").authenticated()
.and()
.csrf()
.disable()
.headers()
.frameOptions().disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout()
.permitAll()
.exceptionHandling().authenticationEntryPoint(securityException401EntryPoint());
}
관련 행은 다음과 같습니다.
.exceptionHandling().authenticationEntryPoint(securityException401EntryPoint());
여기 해결책이 있습니다.
http
.authenticationEntryPoint(authenticationEntryPoint)
AuthenticationEntryPoint 소스 코드:
@Component
public class Http401UnauthorizedEntryPoint implements AuthenticationEntryPoint {
private final Logger log = LoggerFactory.getLogger(Http401UnauthorizedEntryPoint.class);
/**
* Always returns a 401 error code to the client.
*/
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
ServletException {
log.debug("Pre-authenticated entry point called. Rejecting access");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
}
}
Spring Boot 2에서는 람다 표현을 사용한 간단한 접근법:
@Override
public void configure(HttpSecurity http) throws Exception {
http.
...
.exceptionHandling()
.authenticationEntryPoint((request, response, e) -> {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setContentType("application/json");
response.getWriter().write("{ \"error\": \"You are not authenticated.\" }");
})
...
}
연장해야 합니다.AuthenticationEntryPoint예외에 따라 커스터마이즈를 수행합니다.
@ControllerAdvice
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException {
// 401
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed");
}
@ExceptionHandler (value = {AccessDeniedException.class})
public void commence(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
// 401
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization Failed : " + accessDeniedException.getMessage());
}
}
SecurityConfig에서 다음과 같이 위의 커스텀 AuthenticationEntryPoint를 지정합니다.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity (prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new MyAuthenticationEntryPoint());
}
}
일의 메커니즘에 관심이 있는 사람.
설정하지 않으면http.exceptionHandling().authenticationEntryPoint()봄을 이용하다defaultAuthenticationEntryPoint()및 방법ExceptionHandlingConfigurer.createDefaultEntryPoint()돌아온다new Http403ForbiddenEntryPoint()
그래서 그냥 만들어요.Http401UnauthorizedEntryPoint()위의 답변은 중복되지 않았습니다.
추신: Spring Security 5.2.5에 대한 실제 정보입니다.풀어주다
언급URL : https://stackoverflow.com/questions/30643029/spring-security-anonymous-401-instead-of-403
'programing' 카테고리의 다른 글
| 각도 지연 방법JS 인스턴트 검색? (0) | 2023.03.21 |
|---|---|
| $http가 요청으로 쿠키를 보내지 않음 (0) | 2023.03.16 |
| Jquery - Uncarched TypeError: 'in' 연산자를 사용하여 다음 위치에서 '324'를 검색할 수 없습니다. (0) | 2023.03.16 |
| 중첩된 JSON: 개체에 새 항목을 추가하는 방법(푸시) (0) | 2023.03.16 |
| React를 사용하여 구성 파일을 저장하고 읽는 방법 (0) | 2023.03.16 |