Authentication

seongha_h·2024년 7월 7일

Spring

목록 보기
4/6

참고 : https://velog.io/@on5949/SpringSecurity-Authentication-과정-정리

위 링크가 너무나도 도움이 되었습니다. 제가 부족하다면 참고하시면 좋을것 같습니다.

Authentication 의 인증

의문

아래 Authentication 객체에서 authenticate 라는 메서드에서 실제 비밀번호 인증을 진행합니다.
이때 AuthenticationManger - provider - userdetailsService 순서대로 인증을 진행한다고 합니다.
그러나 저는 userDetailsService 를 override하여 유저 정보를 가져오는 것만 구현했는데 어떻게 인증이 진행되는 것인지 궁금했습니다.
이에 의문점이 생겨서 코드를 뜯어보게 되었습니다.

 @Transactional
    public TokenDto signIn(SignInDto signInDto) {
        //아이디 패스워드로 Authentication 객체 생성
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(
                	signInDto.getUserId(), signInDto.getPassword()
                );

        //실제 검증
        //AuthenticationManger - provider - userdetail service 로 인증
        Authentication authentication = authenticationManagerBuilder
                .getObject()
                .authenticate(authenticationToken);

        TokenDto tokenDto = jwtTokenProvider.generateToken(authentication);
        return tokenDto;
    }

위 코드에서 UsernamePasswordAuthenticationToken 은 AbstractAuthenticationToken 을 상속(extends) 받아 사용하고, 이는 Authentication를 구현하고 있습니다.
따라서 Authentication 에 해당하는 변수에 사용할 수 있습니다.

UsernamePasswordAuthenticationToken 는 아이디 비밀번호만 가지고 있고 Authenticated 가 false로 설정되어 있습니다.

이를 AuthenticationManager 에 전달하고, AuthenticationProvider 에서 인증을 진행합니다. 이때 유저 정보를 DB에서 불러오기 위해서 UserDetailsService 인터페이스를 사용하게 됩니다.

Authentication

간단하게 설명하자면 Authentication에는 두가지 목적이 있습니다.

  • 유저가 전달한 credentials를 AuthenticationManager에 전달하기 위해 (이 경우 isAuthenticated() 는 false를 반환합니다.
  • Authenticated 된 유저를 나타낼때

Authentication은 다음 4가지를 포함합니다.

  • principal : 유저 식별/구별하는 요소 , username/password에서는 UserDetail이 사용됩니다.
  • credentials : 주로 비밀번호, 보통 인증이 완료되면 지워집니다.
  • authorities : 권한

그리고 isAuthenticated(인증여부) 까지 총 4가지를 가지고 있습니다.

AuthenticationManager

이 인터페이스는 ProviderManager 가 구현하고 있습니다.

이 구현체의 역할은 AuthenticationProvider 들을 가지고 있고, 이 provider 들을 순회하면서 null 또는 Exception 이 아닌 값이 나올 때까지 동작합니다.

값이 나왔다면 Authentication 객체에서 비밀번호만 지우고 반환하게 됩니다.

AuthenticationProvider

provider 는 AuthenticationManager 에서 호출하여 진짜 인증을 할 때 사용합니다.

authenticate 메서드를 통해 인증을 하고, supports 메서드를 통해 해당 타입의 Authentication을 통해 인증가능한지 boolean 으로 리턴합니다.
(Authenticaiton 인증이 아니라 다른 인증방법이 있을 시 오버라이드하여 사용)

public interface AuthenticationProvider {
	// Authentication 에 대해 인증을 진행한다.
  // ProviderManager(AuthenticationManager) 에서 루프를 돌면서 호출함
	Authentication authenticate(Authentication authentication) throws AuthenticationException;
    
	// 이 Authentication 이 처리 가능한지 알려주는 메서드
  // 이 또한 ProviderManager 에서 호출한다.
	boolean supports(Class<?> authentication);

}

DaoAuthenticationProvider 를 보면 AuthenticationProvider 를 구현하고 있습니다.

DaoAuthenticationProvider 에서 다양한 메서드가 있는데
추상 클래스에 있는 authenticate 메서드가 실질적인 인증을 담당합니다.

//추상 클래스 상속
public class DaoAuthenticationProvider 
extends AbstractUserDetailsAuthenticationProvider

//추상 클래스는 인터페이스 구현
public abstract class AbstractUserDetailsAuthenticationProvider
		implements AuthenticationProvider, InitializingBean, MessageSourceAware

이때 구현체에서 구현하는 retrieveUser 메서드를 통해 DB에서 유저 정보를 가져오게 되는데 이때 사용하는 메서드가 loadUserByUserName 메서드입니다.

UserDetailsService

따라서 우리는 UserDetailsService 를 구현하는 구현체를 만들어 등록하면 됩니다.


profile
https://github.com/Fixtar

0개의 댓글