Spring, Spring boot

스프링 시큐리티 config

ron_nie 2024. 1. 10. 16:07
728x90

코드

package com.rowoon.myblog.config;

import com.rowoon.myblog.service.UserDetailService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.stereotype.Service;

import static org.springframework.boot.autoconfigure.security.servlet.PathRequest.toH2Console;

@RequiredArgsConstructor
@Configuration
public class WebSecurityService {

    private final UserDetailService userDetailService;

    // 1. 스프링 시큐리티 기능 비활성화
    @Bean
    public WebSecurityCustomizer configure() {
        return (web) -> web.ignoring()
                .requestMatchers(toH2Console())
                .requestMatchers("/static/**");
    }

    // 2. 특정 http 요청에 대한 웹 기반 보안 구성
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .authorizeRequests() // 3. 인증, 인가 설정
                .requestMatchers("/login", "/signup", "/user").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin() // 4. 폼 기반 로그인 설정
                .loginPage("/login")
                .defaultSuccessUrl("/articles")
                .and()
                .logout() // 5. 로그아웃 설정
                .logoutSuccessUrl("/login")
                .invalidateHttpSession(true)
                .and()
                .csrf().disable() // 6. csrf 비활성화
                .build();
    }

    // 7. 인증 관리자 권한 설정
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http, BCryptPasswordEncoder bCryptPasswordEncoder, UserDetailService userDetailService) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(userDetailService) // 8. 사용자 정보 서비스 설정
                .passwordEncoder(bCryptPasswordEncoder)
                .and()
                .build();
    }

    // 9. 패스워드 인코더로 사용할 빈 등록
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

설명

1. 스프링 기능 비활성화

@Bean
    public WebSecurityCustomizer configure() {
        return (web) -> web.ignoring()
                .requestMatchers(toH2Console())
                .requestMatchers("/static/**");
    }

일반적으로 정적 리소스에 설정 하지만 정적 리소스 하위 경로에 있는 리소스와 데이터베이스인 h2 콘솔은 ignore 설정했음

2. 특정 http 요청에 대해 웹 기반 보안 구성

 @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .authorizeRequests() // 3. 인증, 인가 설정
                .requestMatchers("/login", "/signup", "/user").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin() // 4. 폼 기반 로그인 설정
                .loginPage("/login")
                .defaultSuccessUrl("/articles")
                .and()
                .logout() // 5. 로그아웃 설정
                .logoutSuccessUrl("/login")
                .invalidateHttpSession(true)
                .and()
                .csrf().disable() // 6. csrf 비활성화
                .build();
    }

인증 / 인가 및 로그인, 로그아웃 관련 설정 할 수 있다

3. 특정 경로에 대한 액세스 설정

return http
          .authorizeRequests() // 3. 인증, 인가 설정
          .requestMatchers("/login", "/signup", "/user").permitAll()
          .anyRequest().authenticated()
          .and()
  • requestMatchers() : 특정 요청과 일치하는 url에 대한 엑세스 설정
  • permitAll() : 누구나 접근이 가능하게 설정 해당 url로 요청이 오면 인증/인가 없이도 접근 가능
  • anyRequest() : 위에서 설정한 url 이외의 요청에 대해서 설정
  • authenticated() : 별도의 인가는 필요하지 않지만 인증이 성공한 상태여야 접근 가능

4. 폼 기반 로그인 설정

.formLogin() // 4. 폼 기반 로그인 설정
          .loginPage("/login")
          .defaultSuccessUrl("/articles")
          .and()
  • loginPage("/login") : 로그인 페이지 경로 설정
  • defaultSuccessUrl("/articles") : 로그인이 완료되었을 때 경로 설정

5. 로그아웃 설정

.logout() // 5. 로그아웃 설정
          .logoutSuccessUrl("/login")
          .invalidateHttpSession(true)
          .and()
  • logoutSuccessUrl("/login") : 로그아웃이 완료되었을 때 이동할 경로
  • invalidateHttpSession(true) : 로그아웃 이후에 세션을 전체 삭제할지 여부 설정

6. csrf 설정 비활성화

.csrf().disable() // 6. csrf 비활성화

원래는 활성화 해두는게 좋으나 실습할때는 비활성화 해뒀음

7. 인증 관리자 관련 설정

@Bean
    public AuthenticationManager authenticationManager(HttpSecurity http, BCryptPasswordEncoder bCryptPasswordEncoder, UserDetailService userDetailService) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(userDetailService) // 8. 사용자 정보 서비스 설정
                .passwordEncoder(bCryptPasswordEncoder)
                .and()
                .build();
    }

사용자 정보를 가져올 서비스를 재정의 하거나, 인증방법, 예를들어 LDAPm JDBC 기반 인증등을 설정할 때 사용

8. 사용자 서비스 설정

  • .userDetailsService(userDetailService) : 사용자 정보를 가져올 서비스 설정 이때 설정하는 서비스 클래스는 반드시 UserDetailsService를 상속받은 클래스여야 한다
  • passwordEncoder(bCryptPasswordEncoder) : 비밀번호를 암호화 하기 위한 인코더

9. 패스워드 인코더 빈등록

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
반응형