[TIL] Spring Security๋ž€?

๋ƒ ๋ƒ ๋นˆยท2025๋…„ 1์›” 9์ผ
post-thumbnail

๐ŸŒŸ ๋“ค์–ด๊ฐ€๋ฉฐ

Spring Security๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์†์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” Spring ์ƒํƒœ๊ณ„์˜ ๊ฐ•๋ ฅํ•œ ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค. ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ, ์„ธ์…˜ ๊ด€๋ฆฌ, ๊ถŒํ•œ ๊ด€๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ณด์•ˆ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ•„์ˆ˜์ ์ธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ Spring Security๋ž€?

Spring Security๋Š” Spring ํ”„๋ ˆ์ž„์›Œํฌ ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ธ์ฆ(Authentication)๊ณผ ์ธ๊ฐ€(Authorization) ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ณด์•ˆ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

๐Ÿ“– ์ฃผ์š” ๊ฐœ๋…

  1. ์ธ์ฆ (Authentication)
  • ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.
  • ์˜ˆ) ๋กœ๊ทธ์ธ ์‹œ ID์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ์‚ฌ์šฉ์ž ํ™•์ธ.
  • ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์ธ์ฆ ๊ตฌ์กฐ(Spring Security Authentication Architecture)

    ์ธ์ฆ ์ˆœ์„œ

    1. ์‚ฌ์šฉ์ž ์š”์ฒญ (Actor)
      ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ด ์š”์ฒญ์—๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํฌํ•จ๋œ UsernamePasswordAuthenticationToken์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

    2. Security Filter Chains
      Security Filter Chains๋Š” ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ•„ํ„ฐ๋“ค์˜ ์ฒด์ธ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฒด์ธ์—์„œ Authentication Filter๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ธ์ฆ ๊ณผ์ •์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

    3. AuthenticationManager ํ˜ธ์ถœ
      Security Filter Chains๋Š” ์š”์ฒญ์„ AuthenticationManager์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋งค๋‹ˆ์ €๋Š” ์ธ์ฆ ์ž‘์—…์˜ ์ค‘์‹ฌ์œผ๋กœ, ์—ฌ๋Ÿฌ AuthenticationProvider๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

    4. AuthenticationProvider ํ™•์ธ
      AuthenticationManager๋Š” ์š”์ฒญ์„ ์ ์ ˆํ•œ AuthenticationProvider์— ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค. Spring Security์—์„œ๋Š” ๋‹ค์–‘ํ•œ ์ธ์ฆ ๋ฐฉ์‹์„ ์ง€์›ํ•˜๋ฉฐ, ๊ฐ ๋ฐฉ์‹์— ๋”ฐ๋ผ Provider๊ฐ€ ์„ ํƒ๋ฉ๋‹ˆ๋‹ค.

    5. PasswordEncoder ์‚ฌ์šฉ
      AuthenticationProvider๋Š” ์ „๋‹ฌ๋ฐ›์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ PasswordEncoder๋ฅผ ํ†ตํ•ด ์ธ์ฝ”๋”ฉํ•˜๊ฑฐ๋‚˜ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. Spring Security๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ BCryptPasswordEncoder๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

    6. UserDetailsService ํ˜ธ์ถœ
      AuthenticationProvider๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด UserDetailsService๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด ์„œ๋น„์Šค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋˜๋Š” ๋‹ค๋ฅธ ์ €์žฅ์†Œ์—์„œ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

    7. UserDetails ๋ฐ˜ํ™˜
      UserDetailsService๋Š” ์ธ์ฆ ์š”์ฒญ์— ์‚ฌ์šฉ๋œ ์‚ฌ์šฉ์ž ์ด๋ฆ„์— ํ•ด๋‹นํ•˜๋Š” UserDetails ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด์—๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๊ถŒํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    8. ์‚ฌ์šฉ์ž ์ •๋ณด ํ™•์ธ
      ๋ฐ˜ํ™˜๋œ UserDetails๋ฅผ ์‚ฌ์šฉํ•ด ์ธ์ฆ ์ž‘์—…์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ๋ฐ›์€ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์ €์žฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ผ์น˜ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    9. ์ธ์ฆ ์„ฑ๊ณต ์ฒ˜๋ฆฌ
      ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜๋ฉด ์ธ์ฆ์ด ์„ฑ๊ณต์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ AuthenticationProvider๊ฐ€ AuthenticationManager๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    10. Authentication ๊ฐ์ฒด ๋ฐ˜ํ™˜
      AuthenticationManager๋Š” ์ธ์ฆ๋œ Authentication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Security Filter Chains์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    11. SecurityContextHolder์— ์ €์žฅ
      Authentication Filter๋Š” ์ธ์ฆ ์ •๋ณด๋ฅผ SecurityContextHolder์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ์ปจํ…์ŠคํŠธ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „๋ฐ˜์—์„œ ์ธ์ฆ ์ •๋ณด๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

    12. ์š”์ฒญ ์ฒ˜๋ฆฌ ์™„๋ฃŒ
      ์ตœ์ข…์ ์œผ๋กœ ์š”์ฒญ์€ ์ธ์ฆ์ด ์™„๋ฃŒ๋œ ์ƒํƒœ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‹ค๋ฅธ ๊ณ„์ธต(์ปจํŠธ๋กค๋Ÿฌ ๋“ฑ)์œผ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

    [์ •๋ฆฌ]

    1. ์‚ฌ์šฉ์ž โ†’ ์š”์ฒญ ์ƒ์„ฑ
    2. Security Filter Chains์—์„œ ์ธ์ฆ ์ž‘์—… ์‹œ์ž‘
    3. AuthenticationManager์™€ AuthenticationProvider๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ธ์ฆ ์ˆ˜ํ–‰
    4. ์ธ์ฆ ์„ฑ๊ณต ์‹œ ์ธ์ฆ ์ •๋ณด๋ฅผ SecurityContextHolder์— ์ €์žฅ
    5. ์ดํ›„ ์š”์ฒญ ์ฒ˜๋ฆฌ
  1. ์ธ๊ฐ€ (Authorization)
  • ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ๋ฆฌ์†Œ์Šค๋‚˜ ๊ธฐ๋Šฅ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

  • ์˜ˆ) ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋Š” ROLE_ADMIN ๊ถŒํ•œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ.

    • Spring Security๋Š” ๊ถŒํ•œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

      @PreAuthorize("hasRole('ADMIN')")
      @GetMapping("/admin")
      public String adminPage() {
         return "Admin Page";
      }
  1. ์„ธ์…˜ ๊ด€๋ฆฌ
  • ๋กœ๊ทธ์ธ ์ƒํƒœ ์œ ์ง€, ์„ธ์…˜ ํƒ€์ž„์•„์›ƒ ์„ค์ • ๋“ฑ ์‚ฌ์šฉ์ž์˜ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  1. ๋ณด์•ˆ ํ•„ํ„ฐ ์ฒด์ธ (Security Filter Chain)
  • ์š”์ฒญ์ด ์„œ๋ฒ„์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์ผ๋ จ์˜ ํ•„ํ„ฐ๋ฅผ ํ†ตํ•ด ๋ณด์•ˆ ๊ฒ€์ฆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ Spring Security์˜ ํŠน์ง•

  1. ๊ฐ•๋ ฅํ•œ ๋ณด์•ˆ ๊ธฐ๋Šฅ
  • CSRF, CORS, ์„ธ์…˜ ๊ณ ์ • ๊ณต๊ฒฉ ๋ฐฉ์ง€ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ œ๊ณต.
  1. ๋†’์€ ์œ ์—ฐ์„ฑ
  • ๋‹ค์–‘ํ•œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ์˜ต์…˜์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ.
  1. ํ†ตํ•ฉ์„ฑ
  • Spring Boot์™€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ†ตํ•ฉ๋˜๋ฉฐ, OAuth2, JWT ๊ฐ™์€ ์ตœ์‹  ์ธ์ฆ ๋ฐฉ์‹๋„ ์ง€์›.
  1. ํ‘œ์ค€ ์ค€์ˆ˜
  • JSR-250, JEE Security ํ‘œ์ค€ API์™€์˜ ํ†ตํ•ฉ ์ง€์›.

๐Ÿ—๏ธ Spring Security์˜ ์ฃผ์š” ์ปดํฌ๋„ŒํŠธ

  1. SecurityContext
    ํ˜„์žฌ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ์ปจํ…์ŠคํŠธ.
  2. AuthenticationManager
    ์‚ฌ์šฉ์ž ์ธ์ฆ์˜ ํ•ต์‹ฌ ์—ญํ• ์„ ์ˆ˜ํ–‰.
  3. Authentication
    ์ธ์ฆ ์ •๋ณด๋ฅผ ๋‹ด๋Š” ๊ฐ์ฒด.
  4. GrantedAuthority
    ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ€์ง„ ๊ถŒํ•œ ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋ƒ„.

๐Ÿ“‹ Spring Security ์ฃผ์š” ์–ด๋…ธํ…Œ์ด์…˜

  1. @EnableWebSecurity
    Spring Security ์„ค์ •์„ ํ™œ์„ฑํ™”.
  2. @PreAuthorize / @PostAuthorize
    ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ์ „/ํ›„์— ๊ถŒํ•œ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰.
    @PreAuthorize("hasRole('ADMIN')")
     public void adminOnlyMethod() { ... }
  3. @Secured
    ํŠน์ • ์—ญํ•  ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œํ•œ.
    @Secured("ROLE_USER")
     public void userMethod() { ... }
  4. @WithMockUser
    ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ๊ฐ€์งœ ์‚ฌ์šฉ์ž๋กœ ์ธ์ฆ.

๐Ÿ“ Spring Security ์„ค์ •: ํšŒ์›๊ฐ€์ž…๋ถ€ํ„ฐ ๊ถŒํ•œ ๊ด€๋ฆฌ๊นŒ์ง€

1๏ธโƒฃ ํšŒ์›๊ฐ€์ž…

ํšŒ์›๊ฐ€์ž… ์‹œ์—๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋ฉฐ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๋ฐ˜๋“œ์‹œ BCrypt์™€ ๊ฐ™์€ ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์•”ํ˜ธํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Service
public class UserService {
    private final PasswordEncoder passwordEncoder;

    public UserService(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    public void registerUser(String username, String password) {
        String encodedPassword = passwordEncoder.encode(password);
        User user = new User(username, encodedPassword, Collections.singletonList("ROLE_USER"));
        userRepository.save(user);
    }
}

2๏ธโƒฃ ๋กœ๊ทธ์ธ

Spring Security๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ UsernamePasswordAuthenticationFilter๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Custom Login ์„ค์ •:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.formLogin()
        .loginPage("/login")
        .defaultSuccessUrl("/home")
        .failureUrl("/login?error=true")
        .permitAll();
}

3๏ธโƒฃ ๋กœ๊ทธ์•„์›ƒ

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.logout()
        .logoutUrl("/logout")
        .logoutSuccessUrl("/login?logout")
        .invalidateHttpSession(true)
        .deleteCookies("JSESSIONID");
}

4๏ธโƒฃ ์„ธ์…˜ ๊ด€๋ฆฌ

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        .maximumSessions(1)
        .maxSessionsPreventsLogin(true);
}

5๏ธโƒฃ ๊ถŒํ•œ ๊ด€๋ฆฌ

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
        .anyRequest().authenticated();
}

๐Ÿ” Spring Security์˜ ๋ณด์•ˆ ๊ณ ๋ ค์‚ฌํ•ญ

  1. HTTPS ์‚ฌ์šฉ ํ•„์ˆ˜
    HTTPS๋Š” ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”๋œ ์ฑ„๋„๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

    server:
     ssl:
       key-store: classpath:keystore.p12
       key-store-password: password
       key-store-type: PKCS12
  2. ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”
    Spring Security์—์„œ ์ œ๊ณตํ•˜๋Š” BCryptPasswordEncoder ์‚ฌ์šฉ.

  3. CSRF ๋ณดํ˜ธ
    Spring Security๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ CSRF ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. REST API ์‚ฌ์šฉ ์‹œ ๋น„ํ™œ์„ฑํ™” ๊ฐ€๋Šฅ.
    CSRF(Cross-Site Request Forgery)๋Š” ์•…์˜์ ์ธ ์‚ฌ์ดํŠธ์—์„œ ์š”์ฒญ์„ ๋ณด๋‚ด ์‚ฌ์šฉ์ž์˜ ์˜๋„์™€ ์ƒ๊ด€์—†๋Š” ๋™์ž‘์„ ์‹คํ–‰ํ•˜๋Š” ๊ณต๊ฒฉ์ž…๋‹ˆ๋‹ค.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
  4. JWT์™€ OAuth2
    ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ ๋ฐฉ์‹์œผ๋กœ ์„ธ์…˜ ๊ด€๋ฆฌ์˜ ๋ถ€๋‹ด์„ ์ค„์ž„.

    ๐Ÿ”‘ OAuth2 ๋ฐ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ
    OAuth2๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. Spring Security๋Š” OAuth2๋ฅผ ํ†ตํ•ด ์†Œ์…œ ๋กœ๊ทธ์ธ, API ์ธ์ฆ ๋“ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

    • ๋™์ž‘ ๊ณผ์ •:
      1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฆฌ์†Œ์Šค ์†Œ์œ ์ž(์‚ฌ์šฉ์ž)์—๊ฒŒ ์ธ์ฆ ์š”์ฒญ.
      2. ์‚ฌ์šฉ์ž ๋™์˜ ํ›„ ์ธ์ฆ ์„œ๋ฒ„์—์„œ Access Token ๋ฐœ๊ธ‰.
      3. ํด๋ผ์ด์–ธํŠธ๋Š” Access Token์„ ์‚ฌ์šฉํ•ด ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„ ์ ‘๊ทผ.
      @Override
      protected void configure(HttpSecurity http) throws Exception {
         http.oauth2Login()
             .clientRegistrationRepository(clientRegistrationRepository())
             .authorizedClientService(authorizedClientService());
      }

๐Ÿ“‹ ์ฟ ํ‚ค, ์„ธ์…˜, JWT์˜ ์ฃผ์š” ๋น„๊ต

ํ•ญ๋ชฉ์ฟ ํ‚ค์„ธ์…˜JWT
์ €์žฅ ์œ„์น˜ํด๋ผ์ด์–ธํŠธ์„œ๋ฒ„ํด๋ผ์ด์–ธํŠธ
๋ณด์•ˆXSS ๊ณต๊ฒฉ์— ์ทจ์•ฝ์„œ๋ฒ„ ๊ด€๋ฆฌ, ๋น„๊ต์  ์•ˆ์ „ํƒˆ์ทจ ์‹œ ์œ„ํ—˜
์ƒํƒœ ์œ ์ง€ํด๋ผ์ด์–ธํŠธ ์ €์žฅ์„œ๋ฒ„์—์„œ ์ƒํƒœ ์œ ์ง€์ƒํƒœ ์ •๋ณด ์ž์ฒด ํฌํ•จ
์„œ๋ฒ„ ๋ถ€๋‹ด๋‚ฎ์Œ๋†’์Œ(์„ธ์…˜ ์ €์žฅ ํ•„์š”)์—†์Œ(Stateless)
๊ฐฑ์‹ /ํ๊ธฐ๊ฐ„๋‹จ๊ฐ„๋‹จ๋ณต์žก(์žฌ๋ฐœ๊ธ‰ ํ•„์š”)
๋ฐ์ดํ„ฐ ํฌ๊ธฐ์ž‘์Œ(4KB ์ œํ•œ)์ œํ•œ ์—†์Œ(์„œ๋ฒ„ ์ธก ์ €์žฅ)ํด๋ผ์ด์–ธํŠธ ํฌ๊ธฐ๋งŒํผ ์ œํ•œ
์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ„๋‹จํ•œ ์ƒํƒœ ์œ ์ง€์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ์„ธ์…˜ ๊ด€๋ฆฌ๋ถ„์‚ฐ ์‹œ์Šคํ…œ, API ์ธ์ฆ

์ฆ‰, ๊ฐ„๋‹จํ•œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ ค๋ฉด ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ณ , ์„œ๋ฒ„ ์ค‘์‹ฌ์˜ ์ธ์ฆ์—๋Š” ์„ธ์…˜์ด, ํ™•์žฅ์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ์ค‘์‹œํ•œ๋‹ค๋ฉด JWT, ์™ธ๋ถ€ ์ธ์ฆ ๋ฐ ์†Œ์…œ ๋กœ๊ทธ์ธ์—๋Š” OAuth2๊ฐ€ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š”๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ์‚ฌ์šฉ ๋ฐฉ์‹ ์„ค๋ช…

1๏ธโƒฃ ์ฟ ํ‚ค

  • ๋™์ž‘ ์›๋ฆฌ:
    • ํด๋ผ์ด์–ธํŠธ ์ธก์— ์ƒํƒœ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜์—ฌ HTTP ์š”์ฒญ๋งˆ๋‹ค ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌ.
  • ์žฅ์ :
    • ์„œ๋ฒ„ ๋ถ€ํ•˜ ๊ฐ์†Œ.
    • ๊ฐ„๋‹จํ•œ ์ƒํƒœ ์ €์žฅ์— ์œ ์šฉ.
  • ๋‹จ์ :
    • XSS ๊ณต๊ฒฉ์— ์ทจ์•ฝ (์ฟ ํ‚ค์— ๋ฏผ๊ฐํ•œ ์ •๋ณด ์ €์žฅ ๊ธˆ์ง€).
    • ๋ฐ์ดํ„ฐ ํฌ๊ธฐ ์ œํ•œ(4KB).
  • ์‚ฌ์šฉ ์‚ฌ๋ก€:
    UI ์„ ํ˜ธ ์„ค์ • ์ €์žฅ.
    ๊ฐ„๋‹จํ•œ ์„ธ์…˜ ๊ด€๋ฆฌ.
    // Spring์—์„œ ์ฟ ํ‚ค ์„ค์ •
    ResponseCookie cookie = ResponseCookie.from("key", "value")
          .httpOnly(true) // XSS ๋ฐฉ์ง€
          .secure(true)  // HTTPS์—์„œ๋งŒ ๋™์ž‘
          .path("/")
          .maxAge(Duration.ofHours(1))
          .build();
    response.addHeader("Set-Cookie", cookie.toString());

2๏ธโƒฃ ์„ธ์…˜

  • ๋™์ž‘ ์›๋ฆฌ:
    ์ƒํƒœ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ €์žฅํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๋Š” ์„ธ์…˜ ID๋งŒ ์ฟ ํ‚ค๋กœ ์ €์žฅ.
  • ์žฅ์ :
    • ์„œ๋ฒ„์—์„œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ ์กฐ์ž‘ ์–ด๋ ค์›€.
    • ์ƒํƒœ ์ •๋ณด ์šฉ๋Ÿ‰ ์ œํ•œ ์—†์Œ.
  • ๋‹จ์ :
    • ์„œ๋ฒ„ ๋ถ€๋‹ด ์ฆ๊ฐ€.
    • ํ™•์žฅ์„ฑ ๋‚ฎ์Œ(๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ ๊ด€๋ฆฌ ์–ด๋ ค์›€).
  • ์‚ฌ์šฉ ์‚ฌ๋ก€:
    • ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ์ƒํƒœ ์œ ์ง€.
    • ์‡ผํ•‘๋ชฐ ์žฅ๋ฐ”๊ตฌ๋‹ˆ.
      // Spring Security ์„ธ์…˜ ์„ค์ •
      @Override
      protected void configure(HttpSecurity http) throws Exception {
         http.sessionManagement()
             .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // ํ•„์š” ์‹œ ์„ธ์…˜ ์ƒ์„ฑ
             .maximumSessions(1)  // ๋™์‹œ ๋กœ๊ทธ์ธ ์ œํ•œ
             .expiredUrl("/session-expired") // ์„ธ์…˜ ๋งŒ๋ฃŒ ์‹œ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
             .maxSessionsPreventsLogin(true); // ์ƒˆ๋กœ์šด ์„ธ์…˜ ์ƒ์„ฑ ๋ฐฉ์ง€
      }

3๏ธโƒฃ JWT

  • ๋™์ž‘ ์›๋ฆฌ:
    ํด๋ผ์ด์–ธํŠธ์— ์ƒํƒœ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ ํ† ํฐ์„ ๋ฐœ๊ธ‰. ์„œ๋ฒ„๋Š” ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š์Œ(Stateless).
  • ์žฅ์ :
    • ์„œ๋ฒ„ ๋ถ€๋‹ด ๊ฐ์†Œ.
    • RESTful API ๋ฐ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์— ์ ํ•ฉ.
  • ๋‹จ์ :
    • ํ† ํฐ ํƒˆ์ทจ ์‹œ ๋ณด์•ˆ ๋ฌธ์ œ ๋ฐœ์ƒ.
    • ๋ฐ์ดํ„ฐ ๊ฐฑ์‹ /ํ๊ธฐ ์–ด๋ ค์›€.
  • ์‚ฌ์šฉ ์‚ฌ๋ก€:
    • ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์ธ์ฆ.
    • API ์ธ์ฆ.
      // Spring์—์„œ JWT ์ƒ์„ฑ
      String jwt = Jwts.builder()
             .setSubject("username")
             .setIssuedAt(new Date())
             .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1์‹œ๊ฐ„ ์œ ํšจ
             .signWith(SignatureAlgorithm.HS256, "secret-key")
             .compact();

๐Ÿ’ก ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์†Œ๋“œ

  1. ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”
PasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode("rawPassword");
  1. ํ˜„์žฌ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = authentication.getName();
  1. ๊ถŒํ•œ ํ™•์ธ
if (authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) {
    // ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ๋กœ์ง
}
  1. JWT ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
Claims claims = Jwts.parser()
        .setSigningKey("secret-key")
        .parseClaimsJws(token)
        .getBody();

์ฐธ๊ณ ๋ฌธํ—Œ

[Spring Security] Spring Security๋ž€? (feat.ํ•™์Šต ์ด์œ )
Spring Security๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž
[SpringBoot] Spring Security๋ž€?
chatGPT ๊ฒ€์ƒ‰


profile
๋‹ค ๋จน์–ด๋ฒ„๋ฆด๊ฑฐ์•ผ!

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