본문 바로가기
❤️‍🔥TIL (Today I Learned)

[TIL] 2022-12-26(41day)

by elicho91 2022. 12. 27.

Spring Security

 


👉 Spring Security 란?

# 개념

 - Spring Security' 프레임워크는 스프링 서버에 필요한 인증 및 인가를 위해 많은 기능을 제공해 줌으로써 개발의 수고를 덜어준다.

 

# 스프링 시큐리티 적용하는 방법

 - '스프링 시큐리티' 프레임워크 추가

// 스프링 시큐리티
implementation 'org.springframework.boot:spring-boot-starter-security'

 

 - '스프링 시큐리티' 활성화 하기

WebSecurityConfig (springboot 2.7이상)

package com.sparta.springsecurity.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity // 스프링 Security 지원을 가능하게 함
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // CSRF 설정
        http.csrf().disable();
        
        http.authorizeRequests().anyRequest().authenticated();

        // 로그인 사용
        http.formLogin();
        
        return http.build();
    }

}

 

WebSecurityConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity // 스프링 Security 지원을 가능하게 함
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                // image 폴더를 login 없이 허용
                .antMatchers("/images/**").permitAll()
                // css 폴더를 login 없이 허용
                .antMatchers("/css/**").permitAll()
                // 어떤 요청이든 '인증'
                .anyRequest().authenticated()
                .and()
                    // 로그인 기능 허용
                    .formLogin()
                    .loginPage("/user/login")
                    .defaultSuccessUrl("/")
                    .failureUrl("/user/login?error")
                    .permitAll()
                .and()
                    // 로그아웃 기능 허용
                    .logout()
                    .permitAll();
    }
}

 

SpringBoot 3v 변경된 코드 확인 authorizeRequests() authorizeHttpRequests()

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // CSRF 설정
        http.csrf().disable();

        http.authorizeHttpRequests().anyRequest().authenticated();

        // 로그인 사용
        http.formLogin();

        return http.build();
    }

 

👉 Spring Security 주요 컴포넌트 확인하기

# Spring Security 와 Filter

 - Spring Security는 요청이 들어오면 Servlet FilterChain(여러 Filter를 chain형태로 묶어놓은 것)을 자동으로 구성한 후 거치게 한다.

 

# SecurityFilterChain

 - Spring 의 보안 Filter를 결정하는데 사용되는 Filter session, jwt 등의 인증방식들을 사용하는데에 필요한 설정을 완전히 분리할 수 있는 환경을 제공

# AbstractAuthenticationProcessingFilter

 - 사용자의 credential을 인증하기 위한 베이스 Filter

 

# UsernamePasswordAuthenticationFilter

 - AbstractAuthenticationProcessingFilter를 상속한 Filter

 - 기본적으로 아래와 같은 Form Login 기반을 사용할 때 username 과 password 확인하여 인증.

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

 

# SecurityContextHolder

 - SecurityContextHolder 에는 스프링 시큐리티로 인증을 한 사용자의 상세 정보를 저장

 - SecurityContext 란? SecurityContextHolder 로 접근할 수 있으며 Authentication 객체를 가지고 있다.

// 예시코드
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
context.setAuthentication(authentication);

SecurityContextHolder.setContext(context);

 

# Authentication

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

 - principal : 사용자를 식별한다. Username/Password 방식으로 인증할 때 보통 UserDetails 인스턴스다.

 - credentials : 주로 비밀번호, 대부분 사용자 인증에 사용하고 다음 비운다. 

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

		<UserDetails>
		@Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        UserRoleEnum role = user.getRole();
        String authority = role.getAuthority();
        System.out.println("authority = " + authority);

        SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
        Collection<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(simpleGrantedAuthority);

        return authorities;
    }

Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

// UsernamePasswordAuthenticationToken는 Authentication을 implements한 
// AbstractAuthenticationToken의 하위 클래스로, 인증객체를 만드는데 사용된다.

 

# UserDetailsService

 - username/password 인증방식을 사용할 때 사용자를 조회하고 검증한 후 UserDetails를 반환한다. Custom하여 Bean으로 등록 후 사용 가능하다.

 

# UserDetails

 - 검증된 UserDetails는 UsernamePasswordAuthenticationToken 타입의 Authentication를 만들 때 사용되며 해당 인증객체는 SecurityContextHolder에 세팅된다. Custom하여 사용가능하다.

 


🙋‍♂️ 소감 : 

스프링 시큐리티는 많은 필터들로 구성되어있어 복잡하게 느껴졌다.

각 필터별로 어떤 역할을 하는지 살펴보고, 스프링시큐리티를 활용한 로그인 기능을 직접 구현해보면서

전체적인 흐름을 이해해야겠다.

😈 아는 내용이라고 그냥 넘어가지 않기! 😈

'❤️‍🔥TIL (Today I Learned)' 카테고리의 다른 글

[TIL] 2022-12-28(43day)  (0) 2022.12.28
[TIL] 2022-12-27(42day)  (0) 2022.12.28
[TIL] 2022-12-23(40day)  (0) 2022.12.26
[TIL] 2022-12-22(39day)  (0) 2022.12.22
[TIL] 2022-12-21(38day)  (0) 2022.12.21

댓글