Spring Security - 회원가입 강화

2024. 4. 16. 16:21개발일지

로그인 할 때 비밀번호 보안 처리하는 방법을 배워서 지난 포스팅에 구현하였다.

 

로그인 할 때 보안 처리 하는것도 중요하지만

애초에 강화하여 가입할 수 있을지 궁금증이 발생하였다.

 

보안 처리 된 패스워드를 읽어 오는 것이 가능한지 무지한 상태였기에

조금 찾아보면 가능하겠지 했다. 

(조금은 개뿔. ㅜㅜ 2일 걸렸다...........)

 

그래서 개인 프로젝트에는

회원 가입할 때 비밀번호를 보안처리하여 가입하는 것을 구현하고자 한다.

 

 

 

package org.example.account_book.Service;

import lombok.RequiredArgsConstructor;
import org.example.account_book.Entity.MemberEntity;
import org.example.account_book.Repository.LoginRepository;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class LoginService implements UserDetailsService {
    private final LoginRepository loginRepository;
    private final PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        //회원 이메일이 존재하는지 조회
        Optional<MemberEntity> memberEntity = loginRepository.findByEmail(email);

        //조회한 데이터가 있으면
        if (memberEntity.isPresent()) {
            return User.withUsername(memberEntity.get().getEmail())
                    //passwordEncoder 비밀번호 보안작업
                    .password(passwordEncoder.encode(memberEntity.get().getPassword()))
                    .roles(memberEntity.get().getRoleType().name())
                    .build();

        } else { //조회된 데이터가 없으면
            throw new UsernameNotFoundException("존재하지 않는 회원입니다.");
        }
    }


}

 

 

 

package org.example.account_book.Service;

import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.security.auth.login.AccountException;
import javax.security.auth.login.LoginException;
import javax.security.sasl.AuthenticationException;


@Service
@RequiredArgsConstructor
public class AuthenticationProviderService implements AuthenticationProvider {
    private final LoginService loginService;
    private final PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) {
        //입력한 email
        String email = authentication.getName();
        //email로 회원 조회
        UserDetails user = loginService.loadUserByUsername(email);

        //입력한 패스워드
        String rawPassword = authentication.getCredentials().toString();
        //보안 처리 된 패스워드
        String hashPassword = user.getPassword();

        checkPassword(rawPassword, hashPassword);

        System.out.println(checkPassword(rawPassword, hashPassword));

        return new UsernamePasswordAuthenticationToken(email, rawPassword, user.getAuthorities());
    }

    private boolean checkPassword(String rawPassword, String hashPassword) {

        //입력한 패스워드와 DB에 보안 처리 되어 저장된 패스워드 비교
        if (passwordEncoder.matches(rawPassword, hashPassword)) {
            return true;
        }
        return false;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

 

 

 

  1. 인증 처리
    • authenticate 메서드는 사용자의 이메일과 비밀번호를 받아 인증을 수행합니다.
    • 이메일을 사용하여 LoginService에서 사용자 정보를 가져옵니다.
    • 입력된 비밀번호와 데이터베이스에 저장된 암호화된 비밀번호를 PasswordEncoder를 사용하여 비교합니다.
    • 비밀번호가 일치하면 UsernamePasswordAuthenticationToken을 반환하여 인증 정보를 제공합니다.
  2. 비밀번호 확인
    • checkPassword 메서드는 입력된 비밀번호와 데이터베이스에 저장된 암호화된 비밀번호를 PasswordEncoder를 사용하여 비교합니다.
    • 비밀번호가 일치하면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
  3. 지원 인증 토큰 확인
    • supports 메서드는 이 AuthenticationProvider가 UsernamePasswordAuthenticationToken 타입의 인증 토큰을 지원하는지 확인합니다.

 

이 코드는 Spring Security의 인증 프로세스에 통합되어 사용자의 이메일과 비밀번호를 안전하게 확인하고, 인증 정보를 제공합니다. 이를 통해 Spring Security 기반의 애플리케이션에서 안전한 사용자 인증을 구현할 수 있습니다.

 

 

 

 

 

참고자료

 

Spring Security로 로그인/회원가입 프로젝트

안녕하세요! 이번 포스팅에서는 Spring Security에 대해 알아보겠습니다. 🤗 Spring Security는 정말 자주 사용하는 기능이자 그만큼 중요하기 때문에 전체적인 내용을 복습할 겸 잊어버리지 않기 위해

shinsunyoung.tistory.com

 

 

 

bcrypt는 salt가 매번 달라지는데 어떻게 match 판단을 그리 잘 할까요?

저번에 bcrypt을 해서, 패스워드를 hashing 하는 것을 썼습니다. 이전 글에서 올려놨던 것과 비교하면 달라진 것이 딱 하나 있습니다. 인자가 하나 추가되었다는 점입니다. String pw 말고도, len을 받는

codingdog.tistory.com

 

 

 

[Spring Security] 로그인/로그아웃 구현 및 타임리프 적용

1. 개요 리엑트와 같은 클라이언트 사이드 렌더링일 경우 JWT 토큰을 사용해 로그인 처리를 했겠지만, 저같은 경우 서버 사이드 렌더링인 타임리프를 사용해 JWT 토큰 사용은 곤란했습니다. 따라

jaykaybaek.tistory.com

 

'개발일지' 카테고리의 다른 글

Team project - 쇼핑몰 구현(1)  (2) 2024.04.26
Team project - 쇼핑몰 구현  (0) 2024.04.22
PaginationUtil  (0) 2024.04.11
SecurityConfig  (0) 2024.04.11
LoginService  (0) 2024.04.11