코드 그라데이션

shop 구현 (1) 시큐리티 관련 본문

Spring/SpringShop

shop 구현 (1) 시큐리티 관련

완벽한 장면 2023. 7. 7. 10:50

시큐리티

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

  @Override
  public void commence(HttpServletRequest request, HttpServletResponse response,
      AuthenticationException authException) throws IOException, ServletException {
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); 
    // 인증에 대한 접근 권한을 판단. 
    // 이제 이걸 쓸 거다.
  }
}

- 웹에서 들어온 요청을 가지고 인증 또는 인가에 관련된 작업을 하다가 예외가 발생했을 때 어떻게 할지를 규정해놓음.

=> 여기서는 예외가 터지면 401번 에러를 줄 것이라고 규정.

 

확장 포인트

빈 => 자바에서의 객체와 유사한 개념

스프링이 관리하는 객체가 빈이다.

new로 만들지 않아도 바로 쓸 수 있다.

 

그런데 만든 과정도 없고, 메인 메서드가 시작되면서 바로 사용이 가능하다는 걸 우리가 보고 있는데, 그렇다면 빈 등록을 도대체 어디서 할까?

- run이 시작되었을 때, 애플리케이션 실행 시점에 모든 빈 객체를 만든다.

만들 때 의존성이 서로 필요하면 해당 부분에 주입까지 해준다.

일상에서의 상황과 마찬가지로

스프링에서도 라이프사이클이 있는데,

우리도 일상 가운데 정해진 프로세스 속에 개입할 수 있는 부분이나 요소들이 군데군데 있는 것처럼, 스프링에도 있다.

ex) 테스트 코드에서 @BeforeEach, @AfterEach.

 

위 코드 EntryPoint도 동일한 개념 

우리의 요구사항들을 군데군데 개입시킬 수 있도록 확장 포인트들을 스프링에서 제공.

 


@Configuration // 설정
@EnableWebSecurity
//WebSecurityConfigurerAdapter 상속 받는 클래스에 @EnableWebSecurity 선언을 하면
//SpringSecurityFilterChain이 자동 포함 메소드를 오버라이딩 할 수 있습니다.
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  MemberService memberService;

// *** 현재 시큐리티에서 가장 핵심적인 설정 부분.
  @Override
  protected void configure(HttpSecurity http) throws Exception{
    http.formLogin() 
        .loginPage("/members/login") // 로그인 될 때 페이지
        .defaultSuccessUrl("/") // 성공하면 메인으로 리다이렉트
        .usernameParameter("email") // 이메일을 아이디로 받아서(로그인)
        .failureUrl("/members/login/error") // 실패했을 때 페이지
        .and() // 위의 것과 아래의 것이 성격이 다르니까
        .logout() // 로그아웃이 일어나면
        .logoutRequestMatcher(new AntPathRequestMatcher("/members/logout")) //로그아웃
        .logoutSuccessUrl("/"); // 로그아웃에 성공하면 main으로 리다이렉트

// 인가 - 누구에게는 허용하고, 누구에게는 허용을 하지 않을 것인가.
    http.authorizeRequests()
        .mvcMatchers("/","/members/**","/item/**","/images/**").permitAll() // 누구에게나 허용.
        .mvcMatchers("/admin/**").hasRole("ADMIN") // 어드민 하위의 것이면 어드민에게만 허용.
        .anyRequest().authenticated(); // 그리고 그 이외의 요청은 모두 인가가 필요하다.

    http.exceptionHandling() // 예외가 났을 때의 행동
        .authenticationEntryPoint(new CustomAuthenticationEntryPoint());
  }

  @Bean //원두 -> 객체 빈객체 -> SpringContainer 들어갑니다. 이객체 하나로 돌려쓴다.(싱글톤)
  public PasswordEncoder passwordEncoder(){ // 패스워드를 암호화하거나 복호화해서 가져온다.
    return new BCryptPasswordEncoder(); // 비밀번호를 암호화 하는 해시함수
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception{
    auth.userDetailsService(memberService) 
    // 스프링이 생각하는 유저서비스는 너희 애플리케이션에서 이거야를 매핑
        .passwordEncoder(passwordEncoder()); // 매니저가 들고다니면서 설정을 해주는 것이다. 그래서 여기
  }

  @Override
  public void configure(WebSecurity web) throws Exception{
    web.ignoring().antMatchers("/css/**", "/js/**","/img/**"); // 위와 같은 요청들이 들어오면 무시하겠다.
    //(여기서 들어있는 걸로 봤을 때는 정적 파일들을 의미)
  }
}

 

Adapter - 디자인 패턴의 한 종류

신기한게 extend로 하면 괜찮은데 implement로 직접 구현한다고 치면 컴파일 에러가 뜬다.

- implement는 전부 구현해야 하는데, Adapter를 통해 우리가 구현하고 싶은 것만 구현할 수 있도록 편의성을 제공.

그래서 Adapter라는 postfix가 붙어있으면 편하게 설정 등을 할 수 있도록 지원해주는 클래스.

 

HttpSecurity는 웹에서 사용할 것들에 대한 보안 설정 등.

 

싱글톤

- 애플리케이션 통틀어서 그 객체가 하나만 만들어지면 싱글톤

- 어떻게 딱 하나만 존재하게 될 거냐 하는 고민은 안 해도 된다. 

- 우리가 따로 설정하지 않아도 스프링의 디폴트 값은 싱글톤.

- 더블톤, 트리플 톤 같이 설정을 하고싶으면 @Scope 어노테이션을 붙여서 따로 설정해준다.

 

해시함수는 따로 공부할 필요 있음.

 

userDetails 시큐리티에서 사용자를 부르는 명칭.

 

현재 PasswordEncoder는 우리가 빈으로 등록한 것(빈으로 만들어져서 등록된 게 아니라)

-> 그러면 어떻게 꽂지?

-> 빈 생성 메서드가 있으면 이 메서드를 호출하는 것 자체만으로도 싱글톤 객체 자체를 들어오게 된다.(스프링이 관리하는)

 

728x90
Comments