Spring Security 프레임워크

김나영·2023년 6월 29일
0

Spring

목록 보기
22/38

Spring Security 적용

  • Spring 서버에 필요한 인증 및 인가를 위해 많은 기능을 제공해 줌으로써 개발의 수고를 덜어줌

  • Spring 프레임워크가 웹 서버 구현에 편의를 제공해 주는 것과 같음

  • Filter 기반으로 동작

  • Session 방식으로 기본적으로 동작

  • 기본 defalut 로그인 제공

CSRF(Cross-site request forgery)

  • 공격자가 인증된 브라우저에 저장된 쿠키의 세션 정보를 활용하여 웹 서버에 사용자가 의도하지 않은 요청을 전달하는 것

  • CSRF 설정이 되어있는 경우 html에서 CSRF 토큰 값을 넘겨주어야 요청을 수신 가능

  • 쿠키 기반의 취약점을 이용한 공격이기 때문에 REST 방식의 API에서는 disable 가능

  • POST 요청마다 처리해주는 대신 CSRF protection을 disable

    • http.csrf((csrf) -> csrf.disable());

Spring Security 이해

1. Spring Security - Filter Chain

  • Spring에서 모든 호출은 DispatcherServlet을 통과하게 되고 이후에는 각 요청을 담당하는 Controller로 분배

  • 이 때, 각 요청에 대해서 공통적으로 처리해야할 필요가 있을 때 DispatcherServlet 이전에 단계가 필요하며 이것이 Filter

  • Spring Security도 인증 및 인가를 처리하기 위해 Filter 사용

    • Spring Security는 FilterChainProxy를 통해서 상세 로직을 구현

2. Form Login 기반은 인증

  • 인증이 필요한 URL 요청이 들어왔을 때 인증이 되지 않았다면 로그인 페이지를 반환하는 형태

3. UsernamePasswordAuthenticationFilter

  • Spring Security의 필터인 AbstractAuthenticationProcessingFilter를 상속한 Filter

  • 기본적으로 Form Login 기반을 사용할 때 username과 password 확인하여 인증

  • 인증 과정

    • 사용자가 username과 password를 제출

    • UsernamePasswordAuthenticationFilter는 인증된 사용자의 정보가 담기는 인증 객체인 Authentication의 종류 중 하나인 UsernamePasswordAuthenticationToken을 만듦

    • AuthenticationManager에게 넘겨 인증을 시도

    • 실패하면 SecurityContextHolder를 비움

    • 성공하면 SecurityContextHolder에 Authentication를 세팅

1) SecurityContextHolder

  • 인증이 완료된 사용자의 상세 정보(Authentication)를 저장

  • SecurityContext는 SecurityContextHolder로 접근할 수 있음

// 예시코드
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
context.setAuthentication(authentication); // SecurityContext 에 인증 객체 Authentication 를 저장합니다.
SecurityContextHolder.setContext(context);
  • SecurityContext context 생성

    • SecurityContextHolder를 통해서
  • createEmptyContext() : 비어 있는 Context를 만듦

  • Authentication authentication : 인증 객체를 만듦

    • 구현체는 UsernamePasswordAuthenticationToken
  • 생성된 인증된 객체를 context.setAuthentication하면서 넣어줌

  • 만들어진 Context를 Holder에 다시 담아야함

    • Holder에서 새롭게 만들었기 때문에
  • SecurityContextHolder.setContext(context); : 보관소인 SecurityContextHolder에 Context를 담아야함

2) Authentication

  • 현재 인증된 사용자를 나타내며 SecurityContext에서 가져올 수 있음

  • principal : 사용자 식별

    • Username/Password 방식으로 인증할 때 일반적으로 UserDetails 인스턴스
  • credentials : 주로 비밀번호, 대부분 사용자 인증에 사용한 후 비움

  • authorities : 사용자에게 부여한 권한을 GrantedAuthority로 추상화하여 사용

<UserDetails>
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    UserRoleEnum role = user.getRole();
    String authority = role.getAuthority();
    SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
    Collection<GrantedAuthority> authorities = new ArrayList<>();
    authorities.add(simpleGrantedAuthority);
    return authorities;
}
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
  • Authentication을 implements한 AbstractAuthenticationToken의 하위 클래스로, 인증객체를 만드는데 사용

3) UserDetailsService

  • username/password 인증 방식을 사용할 때 사용자를 조회하고 검증한 후 UserDetails 반환

  • Custom하여 Bean으로 등록 후 사용 가능

4) UserDetails

  • 검증된 UserDetails는 UsernamePasswordAuthentication Token 타입의 Authentication를 만들 때 사용

  • 해당 인증 객체는 SecurityContextHolder에 세팅 됨

  • Custom하여 사용 가능

0개의 댓글