Spring Security

0woy·2023년 7월 2일
0

LikeLion

목록 보기
5/6

📌 순천향대학교 멋쟁이 사자처럼 동아리 백엔드 트랙에서 배운 내용을 정리하여 올립니다.

📕 Spring Security

- Spring 기반 애플리케이션의 인증과 권한을 담당하는 하위 프레임워크

  • 스프링 시큐리티는 인증되지 않은 사용자는 서비스를 사용할 수 없게 함.
  • 그러나, 해당 상태로는 서비스 운영이 어렵기에, 설정을 변경해야 함
    로그인 없이 게시물 조회, 네이버 검색 등

📖 HOW TO?

ⓐ main > java > 폴더명 > SecurityConfig.java 생성
ⓑ 하단 코드 작성

//import 생략
//...

@Configuration
@EnableWebSecurity
public class SecurityConfig{
	@Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
    	http.authorizeHttpRequests().requestMatchers(
        new AntPathRequestMatcher("/**")).permitAll();
        
        return http.build();
    }
}

코드 설명
@Configuration : 환경 설정을 의미하는 어노테이션
@EnableWebSecurity: 모든 요청 URL이 스프링 시큐리티의 제어를 받도록 하는 어노테이션

SecurityConfig: 내부적으로 SecurityFilterChain이 동작하여 URL 필터가 적용
나머지: 모든 인증되지 않은 요청 허락 -> 로그인 하지 않아도 모든 페이지 접근 가능

📖 Spring Seucurity Dependency 추가 시

- 서버가 기동되면 스프링 시큐리티의 초기화 작업 & 보안 설정 이루어짐
- 별도의 설정이나 구현 X, 기본적인 웹 보안 기능이 현재 시스텡메 연동

  • 모든 요청은 인증이 되어야 자원에 접근 가능
  • 인증 방식은 폼 로그인 방식, httpBasic 로그인 방식 제공
  • 기본 로그인 페이지 제공
  • 기본 계정 한 개 제공 user/암호값
    - 개발도중 매번 생성되는 랜덤 문자열로 로그인 하는 것은 힘듦
    • application.properties에 기본 name/password 설정 가능

문제점
- 계정 추가, 권한 추가, DB 연동의 복잡함
- 기본적인 보안 기능 외에 시스템에서 필요로 하는 더 부적이고 추가적인 보안기능 필요


📙 사용자 정의 보안기능 구현

스프링 시큐리티의 웹 보안 기능 초기화 및 설정
: WebSecurityConfigurerAdapter

  • Security Dependency를 추가한 이후 기본적인 security를 설정 및 구현 클래스
  • HttpSecurity 라는 세부적 보안기능을 설정할 수 있는 API를 제공하는 클래스 생성
인증 API인가 API
http.formLogin()http.authorizeRequests().antMatchers(/admin)
http.logout()http.authorizeRequests().hasRole(USER)
http.csrf()http.authorizeRequests().permitAll()
http.httpBasic()http.authorizeRequests().authenticated()
http.SessionManagement()http.authorizeRequests().fullyAuthentication()
http.RememberMe()http.authorizeRequests().access(hasRole(USER))
http.ExceptinoHandling()http.authorizeRequests().denyAll()
http.addFilter()

- SecurityConfig 설정 클래스 생성, 인증 & 인가 API를 만들어 보안성을 높힐 수 있음

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
	protected void configure(HttpSecurity http) throws Exception{
    	http
        	.authorizeRequests()	// 요청에 의한 보안검사 시작
            .anyRequest().authenticated() // 어떤 요청에도 보안 검사 진행
       .and()
       		.formLogin();	// 보안 검증은 formLogin 방식
    	}
    }

@EnableWebSecurityWebSecurityconfigurerAdapter를 상속하는 설정 객체에 붙혀주면 SpringSecurityFilterChain에 등록


📒 Form Login 인증

  1. Client에서 Get 방식으로 Home Url자원접근 요청

  2. Server에서는 인증된 사용자만 접근 가능하다고 판단, 인증X -> 로그인 페이지 리다이렉트

  3. Client는 로그인 페이지의 username/pw 입력하여 Post 방식으로 인증 시도

  4. Server에서는 Session ID 생성 후 인증결과를 담은 인증 토큰(Authentication) 생성 & 저장

  5. Client에서 /home 접근 요청 시 세션에 저장된 인증 토큰으로 접근 및 인증 유지

📖 Form Login 인증 필터: UsernamePasswordAuthenticationFilter

UsernamePasswordAuthenticationFilter
- 로그인 인증처리를 담당하고 인증처리에 관련된 요청을 처리하는 필터

① AntPathRequestmatcher(/login)
사용자가 요청한 요청정보 확인 & 요청정보 URL이 /login으로 시작하는지 확인.
요청한다면 다음단계(인증 처리), 그렇지 않으면 다음 필터로 진행(chain.doFilter)
/login URL은 .loginProcessingUrl() 으로 변경 가능

② Authentication에서 실제 인증처리를 함
로그인 페이지에서 입력한 Username과 Password를 인증객체(Authentication)에 저장하여 인증처리(AuthenticationManager)를 맡기는 역할
→ 여기까지가 인증처리 전 필터가 하는 역할

③ AuthenticationManager(인증관리자)는 내부적으로 AuthenticationProvider 에게 인증처리 위임 해당 Provider가 인증처리를 담당하는 클래스로써 인증에 성공/실패 반환

  • 실패한 경우: AuthenticationException 예외를 반환하여 UsernamePasswordAuthenticationFilter로 돌아가서 예외처리 수행
  • 성공한 경우: Authentication 객체를 생성하여 User객체와 Authorities객체를 담아서 AuthenticationManager에게 반환

④ AuthenticationManager는 Provider로부터 반환받은 인증객체(인증결과 유저(User), 유저권한정보(Authorities))를 SecurityContext객체에 저장

⑤ SecurityContext는 Session에도 저장되어 전역적으로 SecurityContext를 참조

⑥ 인증 성공 이후에는 SuccessHandler에서 인증 성공 이후의 로직 수행

📖 정리

  • 인증처리 필터(UsernamePasswordAuthenticationFilter)는 Form 인증처리를 하는 필터로 크게 인증 전과 후의 작업들을 관리.
  • 인증처리 전에는 사용자 인증 정보를 담아 전달하며 인증처리를 맡기고(AuthenticationManager) 성공한 인증 객체를 반환 받아 (전역적으로 인증객체를 참조할 수 있도록 설계된) SecurityContext에 저장.
  • SuccessHandler를 통해 인증 성공 후의 후속 작업 처리.

📗 Logout 처리, LogoutFilter

  1. Client에서 GET방식의 /logout 리소스 호출
  2. Server에서 세션무효화, 인증토큰 삭제, 쿠키정보 삭제 후 로그인페이지로 리다이렉트

① 요청이 Logout Url 인지 확인
② 맞을 경우 SecurityContext에서 인증객체(Authentication)객체를 꺼냄
③ SecurityContextLogoutHandler에서 세션 무효화, 쿠키삭제, clearContext()를 통해 SecurityContext객체 삭제 & 인증객체 null로 만듦
④ SimpleUrlLogoutSuccessHandler를 통해 로그인 페이지로 리다이렉트


📘 동시 세션 제어, 세션 고정 보호, CSRF

A 컴퓨터에서 로그인하여 서비스를 사용하다가 핸드폰 또는 다른 컴퓨터 등에서 서비스를 이용하기 위해 로그인을 시도할 수 있음.
이런 다중 접속시도가 무한정 허용될 경우 여러 문제점을 야기시킬 수 있음
ex) 교육플랫폼 다중 로그인 -> 한 명 강의 결제 후 전체 공유
스프링 시큐리티에서는 이런 세션에 대한 관리 기능도 다음과 같이 제공함

1. 동시 세션 제어

같은 계정(세션)을 동시에 몇 개까지 유지할 수 있게 할 지에 대한 제어 의미
기존 접속해 있는 계정이 존재할 때, 새로운 사용자가 동일한 계정으로 접속을 시도했을 시에 어떻게 대응할지에 대한 방법으로 기존 사용자 로그아웃 또는 현재 사용자가 접속 차단이 있음.

📖 최대 세션 허용 개수 초과시 처리 로직 2가지

1. 이전 사용자 세션 만료
- 신규 로그인 시 기존 로그인 계정의 세션이 만료되도록 설정, 기존 사용자가 자원 접근 시 세션 만료

2. 현재 사용자 인증 실패
- 신규 사용자가 로그인 시도 시 인증 예외 발생

2. 세션 고정 보호

보호라는 말은 공격으로부터 막는다는 의미,
악의적인 해커의 세션 고정 공격을 막기위한 대응 전략임

세션 고정 공격을 방지하기 위해 세션 고정 보호 필요

세션 고정 공격?
공격자가 서버에 접속하여 JSSEIONID를 발급받아서 사용자에게 자신이 발급 받은 세션쿠키를 심어 놓게되면, 사용자가 세션쿠키로 로그인 시도했을 경우 공격자는 같은 쿠키값으로 인증되어 있기 때문에 공격자는 사용자 정보를 공유 하게 됨.

세션 고정 보호?
사용자가 공격자 세션쿠키로 로그인을 시도하더라도 로그인시마다 새로운 세션ID를 발급 하여 제공하게 되면, JSSEIONID가 다르기 때문에, 공격자는 같은 쿠키값으로 사용자 정보를 공유받을 수 없다.

3. 사이트 간 요청 위조: CSRF

  • 사용자가 쇼핑몰에 접속하여 로그인 후 쿠키를 발급받은 뒤 공격자가 사용자의 이메일로 특정 링크 전달
  • 사용자가 해당 링크를 클릭하게 되면 공격용 웹페이지에 접속하게 되고, 해당페이지에 '로또당첨'이라는 이미지가 노출.
  • 로또당첨 이미지를 클릭하면 쇼핑몰에 특정 URL로 요청을 하게되는데 해당 쿠키정보를 가지고 있기 때문에 해당 요청에 대해서 정상적으로 동작

이처럼 사용자의 의도와 무관하게 공격자가 심어 놓은 특정 방식을 통해 자원 요청을 하게 되고 그것을 응답 받을 수 있도록 하는 것을 CSRF 라 함.


📜 참고 자료

스프링 시큐리티 기본 API 및 Filter 이해

0개의 댓글