Sparta/What I Learned

23.1.30

코딩하는 또롱이 2023. 1. 30. 21:07
시큐리티 심화 마저 듣기
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

 

스트림은 왜 느릴까?

https://sigridjin.medium.com/java-stream-api%EB%8A%94-%EC%99%9C-for-loop%EB%B3%B4%EB%8B%A4-%EB%8A%90%EB%A6%B4%EA%B9%8C-50dec4b9974b

 

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://youtu.be/Zl07LUsR6P0

백준 : https://www.acmicpc.net/problem/11286

Heap : 조회 했을때 빠르게 찾을 수 있는 알고리즘

최대힙 : 루트에 제일 큰 수가 들어가는거

최소힙 : 루트에 제일 작은 수가 들어가는거

부모 노드랑 자식 노드랑 바꿀수 있는 공식이 있음
자식 노드가 부모 노드로 갈 때 : 
: idx -1 를 2로 나눈 값 
오오오오오

부모 노드가 자식 노드로 가야할 때 : 
(2*idx) +1 :  레프트 노드로 가고
(2*index_+2 : 라이트 노드로 간다.

'Sparta > What I Learned' 카테고리의 다른 글

23.2.1  (0) 2023.02.02
23.1.31  (0) 2023.02.02
23.1.29  (0) 2023.01.30
23.1.27  (0) 2023.01.30
23.1.26  (0) 2023.01.30