시큐리티 심화 마저 듣기
WebSecurityConfig
@Configuration
@EnableWebSecurity // 스프링 Security 지원을 가능하게 함
@EnableGlobalMethodSecurity(securedEnabled = true) // @Secured 어노테이션 활성화
public class WebSecurityConfig {
private final UserDetailsServiceImpl userDetailsService;
@Bean // 비밀번호 암호화 기능 등록
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
// h2-console 사용 및 resources 접근 허용 설정
// securityFilterChain 보다 우선적으로 걸리는 설정
return (web) -> web.ignoring()
// securityFilterChain 의 authorizeHttpRequests()로 들어오는 것들은 인증을 무시하겠다는 의미
.requestMatchers(PathRequest.toH2Console())
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// CSRF 설정
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/api/user/**").permitAll()
.anyRequest().authenticated();
http.formLogin().loginPage("/api/user/login-page").permitAll();
http.addFilterBefore(new CustomSecurityFilter(userDetailsService, passwordEncoder()), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
🚨 UserDetailsServiceImpl을 선언 해준 부분이 에러나고, antMatchers도 에러 난다. 왜지???
튜터님은 빨간 줄이 안 뜨는데 왜 나만? 코드스니펫 그대론데??!?!?!?!?
✅ 해서 찾아보니까 코드스니펫에는 없지만 @RequiredArgsConstructor 어노테이션을 달아주니까 빨간 줄이 없어졌다. 이 어노테이션은 롬복에서 쓸 수 있게 해주는 어노테이션이고, 지금처럼 초기화되지 않은 final 필드나, @NonNull이 붙은 필드에 대해 생성자를 만들어주는 어노테이션이다!
🚨 antMatchers 얘는 또 뭐가 문제지????
✅ 아하.... 시큐리티 6.0에서부터는 antMatchers가 아닌 requestMatchers라고 해주어야 한다고 한다.....떼잉..... 시큐리티 설정 그거 내가 어케 하는건데,,,,? 6.0 안 쓰고 싶어~~!~!!
@Secured
- Controller 에 "@Secured" 어노테이션으로 권한 설정 가능
- @Secured("권한 이름") 선언
- "@Secured" 어노테이션 활성화 방법
@Configuration @EnableWebSecurity // 스프링 Security 지원을 가능하게 함
@EnableGlobalMethodSecurity(securedEnabled = true) // @Secured 어노테이션 활성화 public class
WebSecurityConfig { ... }
😎 알아두면 유용한 HTTP Status (썬구리 누르면 자세히 알 수 있는 링크 있음)
Code 403 (Forbidden) 클라이언트 오류 상태. 서버에 요청이 전달되었지만, 권한 때문에 거절됨.
Code 401 (Unauthorized) 인증되지 않아서 발생하는 오류.
🐱 401, 403 Error ExceptionHandling 해보기
[WebSecurityConfig]
주석 처리 및 추가
// 접근 제한 페이지 이동 설정
// http.exceptionHandling().accessDeniedPage("/api/user/forbidden");
// 401 Error 처리, Authorization 즉, 인증과정에서 실패할 시 처리
http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint);
// 403 Error 처리, 인증과는 별개로 추가적인 권한이 충족되지 않는 경우
http.exceptionHandling().accessDeniedHandler(customAccessDeniedHandler);
[SecurityExceptionDto]
status 코드와 에러 메세지를 가지고 있는 객체
생성
package com.sparta.springsecurity.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
public class SecurityExceptionDto {
private int statusCode;
private String msg;
public SecurityExceptionDto(int statusCode, String msg) {
this.statusCode = statusCode;
this.msg = msg;
}
}
[CustomAccessDeniedHandler]
403 오류
생성
package com.sparta.springsecurity.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sparta.springsecurity.dto.SecurityExceptionDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
private static final SecurityExceptionDto exceptionDto =
new SecurityExceptionDto(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase());
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException{
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpStatus.FORBIDDEN.value());
try (OutputStream os = response.getOutputStream()) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(os, exceptionDto);
os.flush();
}
}
}
[CustomAuthenticationEntryPoint]
401 오
생성
package com.sparta.springsecurity.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sparta.springsecurity.dto.SecurityExceptionDto;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final SecurityExceptionDto exceptionDto =
new SecurityExceptionDto(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authenticationException) throws IOException {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
try (OutputStream os = response.getOutputStream()) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(os, exceptionDto);
os.flush();
}
}
}
스터디
해쉬 셋은 중복자료에 좋다
square root
스트림은 왜 느릴까?
Java Stream API는 왜 for-loop보다 느릴까?
The Korean Commentary on ‘The Performance Model of Streams in Java 8" by Angelika Langer
sigridjin.medium.com
priorityQueue : 우선순위를 결정하는 큐
큐의 스케줄링은 높은 우선 순위와 낮은 우선 순위를 가지고 결정되는데, 큐의 스케줄링 방법의 하나로 종별을 두어 서비스를 받는 순서에 대해서 우선 순위를 부여한 것.
https://blog.naver.com/goal0208/222895909171
스캐너보다 버퍼리더가 빠르다
[Heap]
힙 설명해주는 유튜브
백준 : https://www.acmicpc.net/problem/11286
Heap : 조회 했을때 빠르게 찾을 수 있는 알고리즘
최대힙 : 루트에 제일 큰 수가 들어가는거
최소힙 : 루트에 제일 작은 수가 들어가는거
부모 노드랑 자식 노드랑 바꿀수 있는 공식이 있음
자식 노드가 부모 노드로 갈 때 :
: idx -1 를 2로 나눈 값
오오오오오
부모 노드가 자식 노드로 가야할 때 :
(2*idx) +1 : 레프트 노드로 가고
(2*index_+2 : 라이트 노드로 간다.