비밀번호를 암호화 하지 않고(평문으로) 저장하면 Security로 로그인 할 수 없음

→ Spring Security는 기본적으로 비밀번호가 암호화되어 있다고 가정

 

Spring Security는 {암호화방식}암호화된비밀번호 형식으로 저장함

// 내부적으로 이런 과정이 일어남
passwordEncoder.matches("1234", "1234")

// java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
// : 암호화 방식을 식별할 수 없다

 

비밀번호 저장 시

  1. BCrypt 암호화 사용
  2. 임시로 평문 사용 (비밀번호 앞에 접두사 {noop} 사용) → user.setPassword("{noop}1234");

 

 

BCryptPasswordEncoder

    @Bean // -> 해당 메서드의 리턴되는 오브젝트를 IoC로 등록해줌
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
// Service
...
private final PasswordEncoder passwordEncoder;

...
    @Transactional
    public void saveUser(User user) {
    	String rawPassword = user.getPassword();
        String encPassword = passwordEncoder.encode(rawPassword);
        user.setPassword(encPassword);
        userRepository.save(user);
    }

 

 

로그인

@Configuration
@EnableWebSecurity // 스프링시큐리티 필터가 스프링 필터체인에 등록됨
public class SecurityConfig{

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable()) // CSRF 비활성화
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/user/**").authenticated() // 인증 필요
                        .requestMatchers("/manager/**").hasAnyRole("ADMIN", "MANAGER") // 권한 확인
                        .requestMatchers("/admin/**").hasRole("ADMIN")
                        .anyRequest().permitAll() // 나머지는 허용
                )
                .formLogin(form -> form
                        .loginPage("/loginForm") // 권한,인증이 필요한 요청은 /loginForm으로 리다이렉트 됨
                        .loginProcessingUrl("/login") // POST /login이 호출되면 시큐리티가 낚아채서 대신 로그인 진행
                        .defaultSuccessUrl("/")); // 성공하면 "/" 메인페이지로 리다이렉트

        return http.build();
    }
}
.loginProcessingUrl("/login")

POST  /login이 호출되면 Spring Security가 낚아채서 로그인을 진행해줌

/login 컨트롤러 만들지 않아도 됨

 

 

로그인 후 세션 생성

로그인 성공 → Security Session 생성
Security ContextHolder라는 키값에 세션 정보를 저장

[객체 계층 구조]
Security Session
ㅤㅤㅤㅤㅤㅤ└── Authentication (인증 객체)
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ└── UserDetails (사용자 상세 정보 객체)

 

1. 로그인 처리

시큐리티가 /login 주소 요청을 낚아채서 로그인을 진행

 

2. UserDetailsService 호출

Spring Security → PrincipalDetailsService.loadUserByUsername() 호출

 

3. 사용자 조회 및 UserDetails 생성

User userEntity = userRepository.findByUsername(username);

return new PrincipalDetails(userEntity);

 

4. Authentication 객체 생성

반환된 UserDetails가 Authentication 객체 내부에 저장

 

5. Security Session 저장

Authentication이 SecurityContextHolder에 저장

 

//UserDetails 구현

public class PrincipalDetails implements UserDetails {

    private User user;
    
    public PrincipalDetails(User user) {
        this.user = user;
    }

    // 해당 유저의 권한을 리턴
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> authorities = new ArrayList<>();

        authorities.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return user.getRole();
            }
        });

        return authorities;
    }
    
    ...

 

@Service
public class PrincipalDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User userEntity = userRepository.findByUsername(username);
        if (userEntity != null) {
            return new PrincipalDetails(userEntity);
        }
        return null;
    }
    // 반환된 UserDetails는 Authentication 내부에 들어감
    // Security Session에는 저 Authentication이 들어감
}

'Back-End > ↳ Spring Security' 카테고리의 다른 글

[Spring Security] JWT  (0) 2025.07.27
[Spring Security] RSA  (1) 2025.07.27
[Spring Security] Session  (1) 2025.07.27
[Spring Security] 권한 설정  (3) 2025.07.27
[Spring Security] 기본 설정 - URL별 접근 권한 설정  (0) 2025.07.26

+ Recent posts