๐Ÿ”ฅ #9 ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‰ฌ ํ›„ ํšŒ์›๊ฐ€์ž…

myeonjiยท2022๋…„ 2์›” 21์ผ
0
  1. ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ํ•˜๋ฉด ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ์ง€์ผœ๋ณด๋‹ค๊ฐ€ ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„๋„๋ก ์„ค์ •ํ•œ๋‹ค.
  2. ๋กœ๊ทธ์ธ ์š”์ฒญ์œผ๋กœ ๋“ค์–ด์˜จ ํŒŒ๋ผ๋ฏธํ„ฐ(username, password)๋ฅผ ๊ฐ€์ง€๊ณ  ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋กœ๊ทธ์ธ์„ ์ง„ํ–‰ํ•œ๋‹ค.
  3. ๋กœ๊ทธ์ธ ์ง„ํ–‰์„ ์™„๋ฃŒํ•œ ํ›„ ์‹œํ๋ฆฌํ‹ฐ ์ „์šฉ(?) ์„ธ์…˜์— ์œ ์ € ์ •๋ณด๋ฅผ ๋„ฃ์–ด๋†“๋Š”๋‹ค. (์ด ๋˜ํ•œ ์Šคํ”„๋ง์ด IoC๋กœ ๊ด€๋ฆฌ)
  4. ์ด๋•Œ, ์‹œํ๋ฆฌํ‹ฐ ์„ธ์…˜ ์•ˆ์—๋Š” User ๊ฐ์ฒด๋ฅผ ์ €์žฅ์‹œํ‚ฌ ์ˆœ ์—†๊ณ , UserDetails ํƒ€์ž…์œผ๋กœ ์ €์žฅ์‹œํ‚จ๋‹ค.
  5. ์‹œํ๋ฆฌํ‹ฐ ์„ธ์…˜ ์•ˆ์— ์žˆ๋Š” ์œ ์ € ์ •๋ณด๋ฅผ DI ๋ฐ›์•„์„œ ์“ฐ๋ฉด ๋œ๋‹ค.

์ด๋•Œ ๋กœ๊ทธ์ธ์ด ๋˜๊ธฐ ์œ„ํ•ด์„œ๋Š” password๊ฐ€ ํ•ด์‰ฌ๋กœ ์•”ํ˜ธํ™”๋œ ์ฑ„๋กœ ๋“ค์–ด์™€์•ผ ํ•œ๋‹ค.


< SecurityConfig ์— ๋„ฃ์„ ๋ฉ”์†Œ๋“œ>

1. encodePWD()

// < SecurityConfig >

	@Bean // IoC๊ฐ€ ๋œ๋‹ค.
    public BCryptPasswordEncoder encodePWD() {
        return new BCryptPasswordEncoder(); // ์ด ๊ฐ์ฒด๋ฅผ ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๊ฒŒ ๋จ. ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ€์ ธ๊ฐ€์„œ ์“ฐ๋ฉด ๋œ๋‹ค.
    }
    
    .
    .
    .
    
// < test>    
	public class EncTest {

    @Test
    public void ํ•ด์‰ฌ_์•”ํ˜ธํ™”ํ™”() {
        String encPassword = new BCryptPasswordEncoder().encode("1234");
        System.out.println("1234 ํ•ด์‰ฌ : " + encPassword);
    }
}

< UserService >

@Service // ์Šคํ”„๋ง์ด ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์„ ํ†ตํ•ด์„œ Bean์— ๋“ฑ๋ก์„ ํ•ด์คŒ. (IoC)
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder encoder;

    @Transactional // ์ „์ฒด๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ commit, ์‹คํŒจํ•˜๋ฉด rollback
    public void ํšŒ์›๊ฐ€์ž…(User user) {
        String rawPassword = user.getPassword(); // ์›๋ณธ (์˜ˆ : 1234)
        String encPassword = encoder.encode(rawPassword); // ํ•ด์‰ฌ
        user.setPassword(encPassword);
        user.setRole(RoleType.USER);
        userRepository.save(user);
    }
}

2. configure(AuthenticationManagerBuilder auth)

	// ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋กœ๊ทธ์ธํ•  ๋•Œ ์–ด๋–ค ์•”ํ˜ธํ™”๋กœ ์ธ์ฝ”๋”ฉํ•ด์„œ ๋น„๋ฒˆ์„ ๋น„๊ตํ• ์ง€ ์•Œ๋ ค์ค˜์•ผ ํ•จ.
    // ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋Œ€์‹  ๋กœ๊ทธ์ธ ํ•จ -> password ๊ฐ€๋กœ์ฑ”
    // ๊ฐ€๋กœ์ฑˆ password๊ฐ€ ํšŒ์›๊ฐ€์ž… ๋  ๋•Œ ๋ฌด์—‡์œผ๋กœ ํ•ด์‰ฌ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์•Œ์•„์•ผํ•จ -> ๊ทธ๋ž˜์•ผ ๊ฐ™์€ ํ•ด์‰ฌ๋กœ ์•”ํ˜ธํ™” ํ•˜๊ณ  DB์— ์žˆ๋Š” ํ•ด์‰ฌ์™€ ๋น„๊ตํ•˜์—ฌ ๋กœ๊ทธ์ธ
    // ์ฆ‰, ํŒจ์Šค์›Œ๋“œ ๋น„๊ตํ•˜๋Š” ๋ฉ”์„œ๋“œ
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(principalDetailService).passwordEncoder(encodePWD()); // passwordEncoder ํ•˜๋Š” ์• ๊ฐ€ encodePWD ์ž„.
    }

< ์ตœ์ข… SecurityConfig >

@Configuration // ๋นˆ ๋“ฑ๋ก (IoC๊ด€๋ฆฌ)
@EnableWebSecurity // Security ํ•„ํ„ฐ๊ฐ€ ๋“ฑ๋ก๋จ = ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ์ด๋ฏธ ํ™œ์„ฑํ™”๋Š” ๋˜์–ด์žˆ์ง€๋งŒ, ์„ค์ •์€ ํ•ด๋‹น ํŒŒ์ผ์—์„œ ํ•  ๊ฒƒ์ž„
@EnableGlobalMethodSecurity(prePostEnabled = true) // ํŠน์ • ์ฃผ์†Œ๋กœ ์ ‘๊ทผ์„ ํ•˜๋ฉด ๊ถŒํ•œ ๋ฐ ์ธ์ฆ์„ ๋ฏธ๋ฆฌ ์ฒดํฌ (์ˆ˜ํ–‰ํ•œ ํ›„์— ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹˜)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PrincipalDetailService principalDetailService;

    // 1. Bean ์–ด๋…ธํ…Œ์ด์…˜์€ ๋ฉ”์„œ๋“œ์— ๋ถ™์—ฌ์„œ ๊ฐ์ฒด ์ƒ์„ฑ์‹œ ์‚ฌ์šฉ
    @Bean // IoC๊ฐ€ ๋œ๋‹ค.
    public BCryptPasswordEncoder encodePWD() {
        return new BCryptPasswordEncoder(); // ์ด ๊ฐ์ฒด๋ฅผ ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๊ฒŒ ๋จ. ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ€์ ธ๊ฐ€์„œ ์“ฐ๋ฉด ๋œ๋‹ค.
    }

    // 2. ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋กœ๊ทธ์ธํ•  ๋•Œ ์–ด๋–ค ์•”ํ˜ธํ™”๋กœ ์ธ์ฝ”๋”ฉํ•ด์„œ ๋น„๋ฒˆ์„ ๋น„๊ตํ• ์ง€ ์•Œ๋ ค์ค˜์•ผ ํ•จ.
    // ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋Œ€์‹  ๋กœ๊ทธ์ธ ํ•จ -> password ๊ฐ€๋กœ์ฑ”
    // ๊ฐ€๋กœ์ฑˆ password๊ฐ€ ํšŒ์›๊ฐ€์ž… ๋  ๋•Œ ๋ฌด์—‡์œผ๋กœ ํ•ด์‰ฌ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์•Œ์•„์•ผํ•จ -> ๊ทธ๋ž˜์•ผ ๊ฐ™์€ ํ•ด์‰ฌ๋กœ ์•”ํ˜ธํ™” ํ•˜๊ณ  DB์— ์žˆ๋Š” ํ•ด์‰ฌ์™€ ๋น„๊ตํ•˜์—ฌ ๋กœ๊ทธ์ธ
    // ์ฆ‰, ํŒจ์Šค์›Œ๋“œ ๋น„๊ตํ•˜๋Š” ๋ฉ”์„œ๋“œ
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(principalDetailService).passwordEncoder(encodePWD()); // passwordEncoder ํ•˜๋Š” ์• ๊ฐ€ encodePWD ์ž„.
    }

    // 3. ํ•„ํ„ฐ๋ง
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable() // csrf ํ† ํฐ ๋น„ํ™œ์„ฑํ™” (ํ…Œ์ŠคํŠธ์‹œ ๊ฑธ์–ด๋‘๋Š”๊ฒŒ ์ข‹์Œ)
                .authorizeRequests() // request๊ฐ€ ๋“ค์–ด์˜ค๋ฉด
                .antMatchers("/", "/auth/**", "/js/**", "/css/**", "/image/**") // ์—ฌ๊ธฐ๋กœ ๋“ค์–ด์˜ค๋ฉด
                .permitAll() // ๋ชจ๋‘ ๊ฐ€๋Šฅ (๋ˆ„๊ตฌ๋‚˜ ๊ฐ€๋Šฅ)
                .anyRequest() // ๊ทธ๊ฒŒ ์•„๋‹Œ ๋‹ค๋ฅธ ๋ชจ๋“  ์š”์ฒญ์€
                .authenticated() // ์ธ์ฆ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค
                .and()
                .formLogin()
                .loginPage("/auth/loginForm") // ์ธ์ฆ์ด ํ•„์š”ํ•œ ์š”์ฒญ์€ ์ด ๋กœ๊ทธ์ธ ํผ์œผ๋กœ ์˜จ๋‹ค
                .loginProcessingUrl("/auth/loginProc") // ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ํ•ด๋‹น ์ฃผ์†Œ๋กœ ์š”์ฒญ์ด ์˜ค๋Š” ๋กœ๊ทธ์ธ์„ ๊ฐ€๋กœ์ฑ„์„œ ๋Œ€์‹  ๋กœ๊ทธ์ธ์„ ํ•œ๋‹ค.
                .defaultSuccessUrl("/");
    }

    // ์ฐธ๊ณ  : .headers().frameOptions().disable() // ์•„์ดํ”„๋ ˆ์ž„ ์ ‘๊ทผ ๋ง‰๊ธฐ
    // ์ฐธ๊ณ  : .csrf().disable() // csrf ํ† ํฐ ๋น„ํ™œ์„ฑํ™” (ํ…Œ์ŠคํŠธ์‹œ ๊ฑธ์–ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Œ)
}

XSS์™€ CSRF

  • XSS ๊ณต๊ฒฉ : ๊ณต๊ฒฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ์‹คํ–‰ํ•˜๊ฒŒ๋” ํ•˜๋Š” ๊ณต๊ฒฉ
  • CSRF ๊ณต๊ฒฉ : ์‚ฌ์ดํŠธ์—์„œ ์˜๋„ํ•˜์ง€ ์•Š์€ API๋ฅผ ๊ณต๊ฒฉ์ž๊ฐ€ ์š”์ฒญํ•˜๋Š” ๊ณต๊ฒฉ

CSRF ๋ฐฉ์–ด ๋ฐฉ๋ฒ•

  • CSRF ํ† ํฐ ์‚ฌ์šฉ : ๋žœ๋คํ•œ ์ˆ˜๋ฅผ ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์— ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ๋ชจ๋“  ์š”์ฒญ(Request)์— ๋Œ€ํ•ด์„œ ์„œ๋ฒ„๋‹จ์—์„œ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ๋ฒ•
// ๋กœ๊ทธ์ธ์‹œ, ๋˜๋Š” ์ž‘์—…ํ™”๋ฉด ์š”์ฒญ์‹œ CSRF ํ† ํฐ์„ ์ƒ์„ฑํ•˜์—ฌ ์„ธ์…˜์— ์ €์žฅ
session.setAttribute("CSRF_TOKEN",UUID.randomUUID().toString());

// ์š”์ฒญ ํŽ˜์ด์ง€์— CSRF ํ† ํฐ์„ ์…‹ํŒ…ํ•˜์—ฌ ์ „์†ก
<input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, CSRF์ฒ˜๋Ÿผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€ ์š”์ฒญ๋“ค์ด API๋กœ ๋“ค์–ด์˜ค๋ฉด ์›์ฒœ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰, ์š”์ฒญ์‹œ์— CSRF ํ† ํฐ์„ ์•ˆ ๊ฐ€์ง€๊ณ  ์š”์ฒญ์„ ํ•˜๋ฉด (=CSRF ํ† ํฐ์ด ์—†์œผ๋ฉด) ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ๋ง‰์•„์ค€๋‹ค.

๊ทธ๋ž˜์„œ ํ…Œ์ŠคํŠธ์‹œ์—๋Š” SecurityConfig.java ์— .csrf().disable() // csrf ํ† ํฐ ๋น„ํ™œ์„ฑํ™” (ํ…Œ์ŠคํŠธ์‹œ ๊ฑธ์–ด๋‘๋Š”๊ฒŒ ์ข‹์Œ) ์ด๋ ‡๊ฒŒ ๋น„ํ™œ์„ฑํ™” ํ•ด๋†“๊ณ  ํ…Œ์ŠคํŠธ ํ•˜๋ฉด ๋œ๋‹ค.

profile
๐Ÿ“š

0๊ฐœ์˜ ๋Œ“๊ธ€